From 78b7349c447984025c19c7b5c995cb0f4288b522 Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Thu, 6 Nov 2025 09:10:03 +0100 Subject: [PATCH 01/16] starting 0.0.6 --- CHANGES.md | 3 +++ pixi.lock | 12 ++++++------ pyproject.toml | 2 +- s2gos-client/pyproject.toml | 2 +- s2gos-common/pyproject.toml | 2 +- s2gos-server/pyproject.toml | 2 +- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8fffecf..516ce64 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,6 @@ +## Changes in version 0.0.6 (in development) + + ## Changes in version 0.0.5 - In `s2gos_client`: diff --git a/pixi.lock b/pixi.lock index d7f4fff..0c161a0 100644 --- a/pixi.lock +++ b/pixi.lock @@ -8731,8 +8731,8 @@ packages: editable: true - pypi: ./s2gos-client name: s2gos-client - version: 0.0.5 - sha256: 4e77f36c91b27649db6e2dc0e765a33bfa9f1078ff34b4abffff4162a9332987 + version: 0.0.6.dev0 + sha256: ec734dcd0fdf156f41f654467b32408d54dd97f00d639c20c8ecf4b7c432813a requires_dist: - click - pydantic @@ -8745,8 +8745,8 @@ packages: editable: true - pypi: ./s2gos-common name: s2gos-common - version: 0.0.5 - sha256: d55cf227264878aabce077c49c92034dc716f1b190427551c8c01832380dbfc7 + version: 0.0.6.dev0 + sha256: 29bba461bdf0b50cf903ce0ef2cc318161518bd025e70f97d98203eb1fd92a88 requires_dist: - pydantic - typer @@ -8754,8 +8754,8 @@ packages: editable: true - pypi: ./s2gos-server name: s2gos-server - version: 0.0.5 - sha256: e76fcb0ac41e85054cac0e96f7ab520d6f5190c6cd238ff627bd1a4913f8026e + version: 0.0.6.dev0 + sha256: 08a7d558ff0af37d676cedb5dba41345302e60a6a1d5678f2e5232adbbc01999 requires_dist: - fastapi - pydantic diff --git a/pyproject.toml b/pyproject.toml index 066e972..fbdc034 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "s2gos-controller" -version = "0.0.5" +version = "0.0.6.dev0" description = "S2GOS control layer comprising a server and client" requires-python = ">=3.10" diff --git a/s2gos-client/pyproject.toml b/s2gos-client/pyproject.toml index 2fe8fa6..2062773 100644 --- a/s2gos-client/pyproject.toml +++ b/s2gos-client/pyproject.toml @@ -4,7 +4,7 @@ [project] name = "s2gos-client" -version = "0.0.5" +version = "0.0.6.dev0" description = "Python client for the ESA DTE-S2GOS synthetic scene generator service" readme = "README.md" authors = [ diff --git a/s2gos-common/pyproject.toml b/s2gos-common/pyproject.toml index 5661a38..7a69166 100644 --- a/s2gos-common/pyproject.toml +++ b/s2gos-common/pyproject.toml @@ -4,7 +4,7 @@ [project] name = "s2gos-common" -version = "0.0.5" +version = "0.0.6.dev0" description = "Python data models for the ESA DTE-S2GOS synthetic scene generator service" readme = "README.md" authors = [ diff --git a/s2gos-server/pyproject.toml b/s2gos-server/pyproject.toml index 475aa03..73725fc 100644 --- a/s2gos-server/pyproject.toml +++ b/s2gos-server/pyproject.toml @@ -4,7 +4,7 @@ [project] name = "s2gos-server" -version = "0.0.5" +version = "0.0.6.dev0" description = "Python server for the ESA DTE-S2GOS synthetic scene generator service" readme = "README.md" authors = [ From b2bd6e9afd65f5fffb12fe8426f4170a69fb74c4 Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Thu, 6 Nov 2025 14:29:37 +0100 Subject: [PATCH 02/16] Changed the `s2gos-client` to use the Eozilla `cuiman` package. --- CHANGES.md | 1 + pixi.lock | 82 +++- pyproject.toml | 7 + s2gos-client/pyproject.toml | 3 +- s2gos-client/src/s2gos_client/__init__.py | 8 +- .../s2gos_client/{api/__init__.py => api.py} | 8 +- .../src/s2gos_client/api/async_client.py | 392 ------------------ .../s2gos_client/api/async_client_mixin.py | 42 -- s2gos-client/src/s2gos_client/api/client.py | 392 ------------------ .../src/s2gos_client/api/client_mixin.py | 42 -- s2gos-client/src/s2gos_client/api/config.py | 114 ----- s2gos-client/src/s2gos_client/api/defaults.py | 13 - .../src/s2gos_client/api/exceptions.py | 24 -- s2gos-client/src/s2gos_client/api/ishell.py | 42 -- .../src/s2gos_client/api/transport/args.py | 80 ---- .../src/s2gos_client/api/transport/httpx.py | 95 ----- .../s2gos_client/api/transport/transport.py | 62 --- .../s2gos_client/{gui/__init__.py => cli.py} | 11 +- s2gos-client/src/s2gos_client/cli/cli.py | 348 ---------------- s2gos-client/src/s2gos_client/cli/client.py | 69 --- s2gos-client/src/s2gos_client/cli/config.py | 64 --- s2gos-client/src/s2gos_client/cli/output.py | 187 --------- .../s2gos_client/{cli/__init__.py => gui.py} | 6 +- s2gos-client/src/s2gos_client/gui/client.py | 156 ------- .../s2gos_client/gui/component/__init__.py | 31 -- .../src/s2gos_client/gui/component/bbox.py | 65 --- .../s2gos_client/gui/component/component.py | 67 --- .../s2gos_client/gui/component/container.py | 134 ------ .../src/s2gos_client/gui/component/factory.py | 116 ------ .../src/s2gos_client/gui/component/impl.py | 148 ------- .../src/s2gos_client/gui/component/json.py | 54 --- .../s2gos_client/gui/component/registry.py | 47 --- .../src/s2gos_client/gui/job_info_panel.py | 92 ---- .../src/s2gos_client/gui/jobs_observer.py | 32 -- .../src/s2gos_client/gui/jobs_panel.py | 288 ------------- .../src/s2gos_client/gui/main_panel.py | 233 ----------- s2gos-client/src/s2gos_client/gui/util.py | 12 - s2gos-client/src/tests/api/__init__.py | 0 .../src/tests/api/test_async_client.py | 105 ----- s2gos-client/src/tests/api/test_client.py | 100 ----- s2gos-client/src/tests/api/test_config.py | 93 ----- s2gos-client/src/tests/api/test_ishell.py | 42 -- .../src/tests/api/transport/__init__.py | 0 .../src/tests/api/transport/test_args.py | 44 -- .../src/tests/api/transport/test_httpx.py | 213 ---------- s2gos-client/src/tests/cli/__init__.py | 0 s2gos-client/src/tests/cli/test_cli.py | 134 ------ s2gos-client/src/tests/cli/test_client.py | 85 ---- s2gos-client/src/tests/cli/test_config.py | 128 ------ s2gos-client/src/tests/cli/test_output.py | 263 ------------ s2gos-client/src/tests/gui/__init__.py | 0 .../src/tests/gui/component/__init__.py | 0 .../src/tests/gui/component/test_component.py | 60 --- .../src/tests/gui/component/test_container.py | 37 -- .../src/tests/gui/component/test_factory.py | 133 ------ .../src/tests/gui/component/test_registry.py | 56 --- s2gos-client/src/tests/gui/test_client.py | 36 -- .../src/tests/gui/test_jobs_info_panel.py | 20 - s2gos-client/src/tests/gui/test_jobs_panel.py | 77 ---- s2gos-client/src/tests/gui/test_main_panel.py | 100 ----- s2gos-client/src/tests/helpers.py | 88 ---- .../__init__.py => tests/test_api.py} | 9 +- s2gos-client/src/tests/test_cli.py | 9 + s2gos-client/src/tests/test_gui.py | 9 + 64 files changed, 133 insertions(+), 5275 deletions(-) rename s2gos-client/src/s2gos_client/{api/__init__.py => api.py} (66%) delete mode 100644 s2gos-client/src/s2gos_client/api/async_client.py delete mode 100644 s2gos-client/src/s2gos_client/api/async_client_mixin.py delete mode 100644 s2gos-client/src/s2gos_client/api/client.py delete mode 100644 s2gos-client/src/s2gos_client/api/client_mixin.py delete mode 100644 s2gos-client/src/s2gos_client/api/config.py delete mode 100644 s2gos-client/src/s2gos_client/api/defaults.py delete mode 100644 s2gos-client/src/s2gos_client/api/exceptions.py delete mode 100644 s2gos-client/src/s2gos_client/api/ishell.py delete mode 100644 s2gos-client/src/s2gos_client/api/transport/args.py delete mode 100644 s2gos-client/src/s2gos_client/api/transport/httpx.py delete mode 100644 s2gos-client/src/s2gos_client/api/transport/transport.py rename s2gos-client/src/s2gos_client/{gui/__init__.py => cli.py} (59%) delete mode 100644 s2gos-client/src/s2gos_client/cli/cli.py delete mode 100644 s2gos-client/src/s2gos_client/cli/client.py delete mode 100644 s2gos-client/src/s2gos_client/cli/config.py delete mode 100644 s2gos-client/src/s2gos_client/cli/output.py rename s2gos-client/src/s2gos_client/{cli/__init__.py => gui.py} (76%) delete mode 100644 s2gos-client/src/s2gos_client/gui/client.py delete mode 100644 s2gos-client/src/s2gos_client/gui/component/__init__.py delete mode 100644 s2gos-client/src/s2gos_client/gui/component/bbox.py delete mode 100644 s2gos-client/src/s2gos_client/gui/component/component.py delete mode 100644 s2gos-client/src/s2gos_client/gui/component/container.py delete mode 100644 s2gos-client/src/s2gos_client/gui/component/factory.py delete mode 100644 s2gos-client/src/s2gos_client/gui/component/impl.py delete mode 100644 s2gos-client/src/s2gos_client/gui/component/json.py delete mode 100644 s2gos-client/src/s2gos_client/gui/component/registry.py delete mode 100644 s2gos-client/src/s2gos_client/gui/job_info_panel.py delete mode 100644 s2gos-client/src/s2gos_client/gui/jobs_observer.py delete mode 100644 s2gos-client/src/s2gos_client/gui/jobs_panel.py delete mode 100644 s2gos-client/src/s2gos_client/gui/main_panel.py delete mode 100644 s2gos-client/src/s2gos_client/gui/util.py delete mode 100644 s2gos-client/src/tests/api/__init__.py delete mode 100644 s2gos-client/src/tests/api/test_async_client.py delete mode 100644 s2gos-client/src/tests/api/test_client.py delete mode 100644 s2gos-client/src/tests/api/test_config.py delete mode 100644 s2gos-client/src/tests/api/test_ishell.py delete mode 100644 s2gos-client/src/tests/api/transport/__init__.py delete mode 100644 s2gos-client/src/tests/api/transport/test_args.py delete mode 100644 s2gos-client/src/tests/api/transport/test_httpx.py delete mode 100644 s2gos-client/src/tests/cli/__init__.py delete mode 100644 s2gos-client/src/tests/cli/test_cli.py delete mode 100644 s2gos-client/src/tests/cli/test_client.py delete mode 100644 s2gos-client/src/tests/cli/test_config.py delete mode 100644 s2gos-client/src/tests/cli/test_output.py delete mode 100644 s2gos-client/src/tests/gui/__init__.py delete mode 100644 s2gos-client/src/tests/gui/component/__init__.py delete mode 100644 s2gos-client/src/tests/gui/component/test_component.py delete mode 100644 s2gos-client/src/tests/gui/component/test_container.py delete mode 100644 s2gos-client/src/tests/gui/component/test_factory.py delete mode 100644 s2gos-client/src/tests/gui/component/test_registry.py delete mode 100644 s2gos-client/src/tests/gui/test_client.py delete mode 100644 s2gos-client/src/tests/gui/test_jobs_info_panel.py delete mode 100644 s2gos-client/src/tests/gui/test_jobs_panel.py delete mode 100644 s2gos-client/src/tests/gui/test_main_panel.py delete mode 100644 s2gos-client/src/tests/helpers.py rename s2gos-client/src/{s2gos_client/api/transport/__init__.py => tests/test_api.py} (51%) create mode 100644 s2gos-client/src/tests/test_cli.py create mode 100644 s2gos-client/src/tests/test_gui.py diff --git a/CHANGES.md b/CHANGES.md index 516ce64..1173d91 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,6 @@ ## Changes in version 0.0.6 (in development) +- Changed the `s2gos-client` to use the Eozilla `cuiman` package. ## Changes in version 0.0.5 diff --git a/pixi.lock b/pixi.lock index 0c161a0..f0ab7a5 100644 --- a/pixi.lock +++ b/pixi.lock @@ -373,6 +373,11 @@ environments: - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/24/ce/c8a41cb0f3044990c8afbdc20c853845a9e940995d4e0cffecafbb5e927b/mkdocs_mermaid2_plugin-1.2.1-py3-none-any.whl + - pypi: ../eozilla/appligator + - pypi: ../eozilla/cuiman + - pypi: ../eozilla/gavicore + - pypi: ../eozilla/procodile + - pypi: ../eozilla/wraptile - pypi: ./s2gos-app-ex - pypi: ./s2gos-client - pypi: ./s2gos-common @@ -732,6 +737,11 @@ environments: - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/24/ce/c8a41cb0f3044990c8afbdc20c853845a9e940995d4e0cffecafbb5e927b/mkdocs_mermaid2_plugin-1.2.1-py3-none-any.whl + - pypi: ../eozilla/appligator + - pypi: ../eozilla/cuiman + - pypi: ../eozilla/gavicore + - pypi: ../eozilla/procodile + - pypi: ../eozilla/wraptile - pypi: ./s2gos-app-ex - pypi: ./s2gos-client - pypi: ./s2gos-common @@ -1081,6 +1091,11 @@ environments: - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/24/ce/c8a41cb0f3044990c8afbdc20c853845a9e940995d4e0cffecafbb5e927b/mkdocs_mermaid2_plugin-1.2.1-py3-none-any.whl + - pypi: ../eozilla/appligator + - pypi: ../eozilla/cuiman + - pypi: ../eozilla/gavicore + - pypi: ../eozilla/procodile + - pypi: ../eozilla/wraptile - pypi: ./s2gos-app-ex - pypi: ./s2gos-client - pypi: ./s2gos-common @@ -1162,6 +1177,18 @@ packages: - python-dateutil - urllib3>=2.1.0 requires_python: ~=3.9 +- pypi: ../eozilla/appligator + name: appligator + version: 0.0.8.dev0 + sha256: 6a4c923c2c6a478fd7d6efd2bf686acef4036328ec7697125e07fc3b77beff23 + requires_dist: + - pydantic + - pyyaml + - typer + - gavicore>=0.0.7 + - procodile>=0.0.7 + requires_python: '>=3.10' + editable: true - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda sha256: 8f032b140ea4159806e4969a68b4a3c0a7cab1ad936eb958a2b5ffe5335e19bf md5: 54898d0f524c9dee622d44bbb081a8ab @@ -2605,6 +2632,21 @@ packages: - pkg:pypi/cryptography?source=hash-mapping size: 1664068 timestamp: 1749539269244 +- pypi: ../eozilla/cuiman + name: cuiman + version: 0.0.8.dev0 + sha256: c2d45f9ba8268315d501434e507801678cc9038cebf78496e83a08a9faeca910 + requires_dist: + - click + - panel + - pydantic + - pyyaml + - typer + - uri-template + - httpx + - gavicore>=0.0.7 + requires_python: '>=3.10' + editable: true - conda: https://conda.anaconda.org/conda-forge/linux-64/cytoolz-1.0.1-py313h536fd9c_0.conda sha256: 4ed6220a9db0c0fbef44b0b6c642e8f20e4d60a52628fc4d995f8c0db5ad942e md5: e886bb6a3c24f8b9dd4fcd1d617a1f64 @@ -3007,6 +3049,16 @@ packages: - pkg:pypi/fsspec?source=hash-mapping size: 145521 timestamp: 1748101667956 +- pypi: ../eozilla/gavicore + name: gavicore + version: 0.0.8.dev0 + sha256: 2f554fb6cb2530441f8a6ef8aa0c639ad7b4f8141ee99e9bec3eb3eb8a417dec + requires_dist: + - click + - pydantic + - typer + requires_python: '>=3.10' + editable: true - conda: https://conda.anaconda.org/conda-forge/noarch/genson-1.3.0-pyhd8ed1ab_0.conda sha256: 2b9e4e8321e355bb8792ccf7722b81e481f3f664d145ad4b851a66ebac2d9c71 md5: d3c12a70d5dc21f05647a80f72a81aa1 @@ -7701,6 +7753,17 @@ packages: - pkg:pypi/pluggy?source=compressed-mapping size: 24246 timestamp: 1747339794916 +- pypi: ../eozilla/procodile + name: procodile + version: 0.0.8.dev0 + sha256: bcfc4f38f4679048eb6b9d2896f5780674d18ca03d90b7a8726f300995953996 + requires_dist: + - pydantic + - pyyaml + - typer + - gavicore>=0.0.7 + requires_python: '>=3.10' + editable: true - conda: https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda sha256: 013669433eb447548f21c3c6b16b2ed64356f726b5f77c1b39d5ba17a8a4b8bc md5: a83f6a2fdc079e643237887a37460668 @@ -8732,7 +8795,7 @@ packages: - pypi: ./s2gos-client name: s2gos-client version: 0.0.6.dev0 - sha256: ec734dcd0fdf156f41f654467b32408d54dd97f00d639c20c8ecf4b7c432813a + sha256: 4af47689f37dddf198bf23ce42a10fed9bc845f77a340bc8a02ac9c2c29075e1 requires_dist: - click - pydantic @@ -8740,7 +8803,8 @@ packages: - typer - uri-template - httpx - - s2gos-common>=0.0.0 + - cuiman + - gavicore requires_python: '>=3.10' editable: true - pypi: ./s2gos-common @@ -9818,6 +9882,20 @@ packages: - pkg:pypi/wrapt?source=hash-mapping size: 62824 timestamp: 1736870265811 +- pypi: ../eozilla/wraptile + name: wraptile + version: 0.0.8.dev0 + sha256: 18aebc189b21453308d28597524a9585b3d999ab3fa52d90fe8a6e3665ced6bc + requires_dist: + - fastapi + - pydantic + - pyyaml + - typer + - uvicorn + - gavicore>=0.0.7 + - procodile>=0.0.7 + requires_python: '>=3.10' + editable: true - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.6.1-pyhd8ed1ab_1.conda sha256: e27b45ca791cfbcad37d64b8615d0672d94aafa00b014826fcbca2ce18bd1cc0 md5: 145c6f2ac90174d9ad1a2a51b9d7c1dd diff --git a/pyproject.toml b/pyproject.toml index fbdc034..cb5169f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,6 +66,13 @@ s2gos-client = { path = "s2gos-client", editable = true } s2gos-common = { path = "s2gos-common", editable = true } s2gos-server = { path = "s2gos-server", editable = true } s2gos-app-ex = { path = "s2gos-app-ex", editable = true } +# TODO: once stable, move into project (conda-forge) dependencies +appligator = { path = "../eozilla/appligator", editable = true } +cuiman = { path = "../eozilla/cuiman", editable = true } +gavicore = { path = "../eozilla/gavicore", editable = true } +procodile = { path = "../eozilla/procodile", editable = true } +wraptile = { path = "../eozilla/wraptile", editable = true } + # Airflow is only available on PyPI apache-airflow-client = "==3.0.2" # Documentation diff --git a/s2gos-client/pyproject.toml b/s2gos-client/pyproject.toml index 2062773..1b4f6cc 100644 --- a/s2gos-client/pyproject.toml +++ b/s2gos-client/pyproject.toml @@ -45,7 +45,8 @@ dependencies = [ "uri-template", "httpx", # local dependency - "s2gos-common>=0.0.0", + "cuiman", + "gavicore", ] [project.scripts] diff --git a/s2gos-client/src/s2gos_client/__init__.py b/s2gos-client/src/s2gos_client/__init__.py index ea2d812..902c555 100644 --- a/s2gos-client/src/s2gos_client/__init__.py +++ b/s2gos-client/src/s2gos_client/__init__.py @@ -4,10 +4,10 @@ from importlib.metadata import version -from .api.async_client import AsyncClient -from .api.client import Client -from .api.config import ClientConfig -from .api.exceptions import ClientError +from .api import AsyncClient +from .api import Client +from .api import ClientConfig +from .api import ClientError __version__ = version("s2gos-client") diff --git a/s2gos-client/src/s2gos_client/api/__init__.py b/s2gos-client/src/s2gos_client/api.py similarity index 66% rename from s2gos-client/src/s2gos_client/api/__init__.py rename to s2gos-client/src/s2gos_client/api.py index c047f04..c077b59 100644 --- a/s2gos-client/src/s2gos_client/api/__init__.py +++ b/s2gos-client/src/s2gos_client/api.py @@ -2,10 +2,10 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -from .async_client import AsyncClient -from .client import Client -from .config import ClientConfig -from .exceptions import ClientError +from cuiman.api import Client +from cuiman.api import AsyncClient +from cuiman.api import ClientConfig +from cuiman.api import ClientError __all__ = [ "AsyncClient", diff --git a/s2gos-client/src/s2gos_client/api/async_client.py b/s2gos-client/src/s2gos_client/api/async_client.py deleted file mode 100644 index d8792b6..0000000 --- a/s2gos-client/src/s2gos_client/api/async_client.py +++ /dev/null @@ -1,392 +0,0 @@ -# generated by gen_client.py: -# filename: async_client.py: -# timestamp: 2025-10-16T17:00:50.945517 - - -from typing import Any, Optional - -from s2gos_common.models import ( - ApiError, - Capabilities, - ConformanceDeclaration, - JobInfo, - JobList, - JobResults, - ProcessDescription, - ProcessList, - ProcessRequest, -) - -from .async_client_mixin import AsyncClientMixin -from .config import ClientConfig -from .ishell import has_ishell as _ # noqa F401 -from .transport import AsyncTransport, TransportArgs -from .transport.httpx import HttpxTransport - - -class AsyncClient(AsyncClientMixin): - """ - The client API for the web service (asynchronous mode). - - Args: - config: Optional client configuration object. If given, - other configuration arguments are ignored. - config_path: Optional path of the configuration file to be loaded - server_url: Optional server URL - user_name: Optional username - access_token: Optional private access token - """ - - def __init__( - self, - *, - config: Optional[ClientConfig] = None, - config_path: Optional[str] = None, - server_url: Optional[str] = None, - user_name: Optional[str] = None, - access_token: Optional[str] = None, - _debug: bool = False, - _transport: Optional[AsyncTransport] = None, - ): - self._config = ClientConfig.create( - config=config, - config_path=config_path, - server_url=server_url, - user_name=user_name, - access_token=access_token, - ) - assert self._config.server_url is not None - self._transport = ( - HttpxTransport( - server_url=self._config.server_url, - debug=_debug, - ) - if _transport is None - else _transport - ) - - @property - def config(self) -> ClientConfig: - return self._config - - def _repr_json_(self): - # noinspection PyProtectedMember - return self.config._repr_json_() - - async def get_capabilities(self, **kwargs: Any) -> Capabilities: - """ - The landing page provides links to the: - * The OpenAPI-definition (no fixed path), - * The Conformance statements (path /conformance), - * The processes metadata (path /processes), - * The endpoint for job monitoring (path /jobs). - - For more information, see [OGC API — Processes — Part 1 - Section - 7.2](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_landing_page). - - Returns: - Capabilities: The landing page provides links to the API definition - (link relations `service-desc` and `service-doc`), - the Conformance declaration (path `/conformance`, - link relation `http://www.opengis.net/def/rel/ogc/1.0/conformance`), - and to other resources. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `500`: A server error occurred. - """ - return await self._transport.async_call( - TransportArgs( - path="/", - method="get", - return_types={"200": Capabilities}, - error_types={"500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - async def get_conformance(self, **kwargs: Any) -> ConformanceDeclaration: - """ - A list of all conformance classes, specified in a standard, that the - server conforms to. - - | Conformance class | URI | - |-----------|-------| - |Core|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/core| - |OGC Process Description|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/ogc-process-description| - |JSON|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/json| - |HTML|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/html| - |OpenAPI Specification 3.0|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/oas30| - |Job list|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/job-list| - |Callback|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/callback| - |Dismiss|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/dismiss| - - For more information, see [OGC API — Processes — Part 1 - Section 7.4](https://docs.ogc.org/is/18-062r2/18- - 062r2.html#sc_conformance_classes). - - - Returns: - ConformanceDeclaration: The URIs of all conformance classes supported - by the server. To support "generic" clients that want - to access multiple OGC API - Processes implementations - and - not "just" a specific API / server, the server declares - the conformance classes it implements and conforms to. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `500`: A server error occurred. - """ - return await self._transport.async_call( - TransportArgs( - path="/conformance", - method="get", - return_types={"200": ConformanceDeclaration}, - error_types={"500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - async def get_processes(self, **kwargs: Any) -> ProcessList: - """ - The list of processes contains a summary of each process the OGC API - - Processes offers, including the link to a more detailed description of - the process. - - For more information, see [OGC API — Processes — Part 1 - Section - 7.9](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_process_list). - - - Returns: - ProcessList: Information about the available processes - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - """ - return await self._transport.async_call( - TransportArgs( - path="/processes", - method="get", - return_types={"200": ProcessList}, - extra_kwargs=kwargs, - ) - ) - - async def get_process(self, process_id: str, **kwargs: Any) -> ProcessDescription: - """ - The process description contains information about inputs and outputs - and a link to the execution-endpoint for the process. The Core does not - mandate the use of a specific process description to specify the - interface of a process. That said, the Core requirements class makes the - following recommendation: - - Implementations **should** consider supporting the OGC process - description. - - For more information, see [OGC API — Processes — Part 1 - Section 7.10](https://docs.ogc.org/is/18-062r2/18- - 062r2.html#sc_process_description). - - Args: - process_id: - kwargs: Optional keyword arguments that may be - used by the underlying transport. - - Returns: - ProcessDescription: A process description. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - """ - return await self._transport.async_call( - TransportArgs( - path="/processes/{processID}", - method="get", - path_params={"processID": process_id}, - return_types={"200": ProcessDescription}, - error_types={"404": ApiError}, - extra_kwargs=kwargs, - ) - ) - - async def execute_process( - self, process_id: str, request: ProcessRequest, **kwargs: Any - ) -> JobInfo: - """ - Create a new job. - - For more information, see [OGC API — Processes — Part 1 - Section - 7.11](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_create_job). - - Args: - process_id: - kwargs: Optional keyword arguments that may be - used by the underlying transport. - request: Mandatory request JSON - - Returns: - JobInfo: Started asynchronous execution. Created job. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - - `500`: A server error occurred. - """ - return await self._transport.async_call( - TransportArgs( - path="/processes/{processID}/execution", - method="post", - path_params={"processID": process_id}, - request=request, - return_types={"201": JobInfo}, - error_types={"404": ApiError, "500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - async def get_jobs(self, **kwargs: Any) -> JobList: - """ - List available jobs. - - For more information, see [OGC API — Processes — Part 1 - Section 11](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_job_list). - - - Returns: - JobList: A list of jobs for this process. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - """ - return await self._transport.async_call( - TransportArgs( - path="/jobs", - method="get", - return_types={"200": JobList}, - error_types={"404": ApiError}, - extra_kwargs=kwargs, - ) - ) - - async def get_job(self, job_id: str, **kwargs: Any) -> JobInfo: - """ - Show the status of a job. - - For more information, see [OGC API — Processes — Part 1 - Section 7.12](https://docs.ogc.org/is/18-062r2/18- - 062r2.html#sc_retrieve_status_info). - - Args: - job_id: Local identifier of a job - kwargs: Optional keyword arguments that may be - used by the underlying transport. - - Returns: - JobInfo: The status of a job. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - - `500`: A server error occurred. - """ - return await self._transport.async_call( - TransportArgs( - path="/jobs/{jobId}", - method="get", - path_params={"jobId": job_id}, - return_types={"200": JobInfo}, - error_types={"404": ApiError, "500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - async def dismiss_job(self, job_id: str, **kwargs: Any) -> JobInfo: - """ - Cancel a job execution and removes it from the jobs list. - - For more information, see [OGC API — Processes — Part 1 - Section 13](https://docs.ogc.org/is/18-062r2/18-062r2.html#Dismiss). - - Args: - job_id: Local identifier of a job - kwargs: Optional keyword arguments that may be - used by the underlying transport. - - Returns: - JobInfo: Information about the job. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - - `500`: A server error occurred. - """ - return await self._transport.async_call( - TransportArgs( - path="/jobs/{jobId}", - method="delete", - path_params={"jobId": job_id}, - return_types={"200": JobInfo}, - error_types={"404": ApiError, "500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - async def get_job_results(self, job_id: str, **kwargs: Any) -> JobResults: - """ - List available results of a job. In case of a failure, list errors - instead. - - For more information, see [OGC API — Processes — Part 1 - Section 7.13](https://docs.ogc.org/is/18-062r2/18- - 062r2.html#sc_retrieve_job_results). - - Args: - job_id: Local identifier of a job - kwargs: Optional keyword arguments that may be - used by the underlying transport. - - Returns: - JobResults: The results of a job. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - - `500`: A server error occurred. - """ - return await self._transport.async_call( - TransportArgs( - path="/jobs/{jobId}/results", - method="get", - path_params={"jobId": job_id}, - return_types={"200": JobResults}, - error_types={"404": ApiError, "500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - async def close(self): - """Close this client.""" - if self._transport is not None: - await self._transport.async_close() diff --git a/s2gos-client/src/s2gos_client/api/async_client_mixin.py b/s2gos-client/src/s2gos_client/api/async_client_mixin.py deleted file mode 100644 index ef1cc5e..0000000 --- a/s2gos-client/src/s2gos_client/api/async_client_mixin.py +++ /dev/null @@ -1,42 +0,0 @@ -from abc import ABC, abstractmethod -from typing import Any - -from s2gos_common.models import ProcessDescription -from s2gos_common.process import ExecutionRequest - - -# noinspection PyShadowingBuiltins -class AsyncClientMixin(ABC): - """ - Extra methods for the API client (synchronous mode). - """ - - @abstractmethod - async def get_process(self, process_id: str, **kwargs: Any) -> ProcessDescription: - """Will be overridden by the actual client class.""" - - async def create_execution_request( - self, - process_id: str, - dotpath: bool = False, - ) -> ExecutionRequest: - """ - Create a template for an execution request - generated from the process description of the - given process identifier. - - Args: - process_id: The process identifier - dotpath: Whether to create dot-separated input - names for nested object values - - Returns: - The execution request template. - - Raises: - ClientError: if an error occurs - """ - process_description = await self.get_process(process_id) - return ExecutionRequest.from_process_description( - process_description, dotpath=dotpath - ) diff --git a/s2gos-client/src/s2gos_client/api/client.py b/s2gos-client/src/s2gos_client/api/client.py deleted file mode 100644 index d5597ae..0000000 --- a/s2gos-client/src/s2gos_client/api/client.py +++ /dev/null @@ -1,392 +0,0 @@ -# generated by gen_client.py: -# filename: client.py: -# timestamp: 2025-10-16T17:00:50.242541 - - -from typing import Any, Optional - -from s2gos_common.models import ( - ApiError, - Capabilities, - ConformanceDeclaration, - JobInfo, - JobList, - JobResults, - ProcessDescription, - ProcessList, - ProcessRequest, -) - -from .client_mixin import ClientMixin -from .config import ClientConfig -from .ishell import has_ishell as _ # noqa F401 -from .transport import Transport, TransportArgs -from .transport.httpx import HttpxTransport - - -class Client(ClientMixin): - """ - The client API for the web service (synchronous mode). - - Args: - config: Optional client configuration object. If given, - other configuration arguments are ignored. - config_path: Optional path of the configuration file to be loaded - server_url: Optional server URL - user_name: Optional username - access_token: Optional private access token - """ - - def __init__( - self, - *, - config: Optional[ClientConfig] = None, - config_path: Optional[str] = None, - server_url: Optional[str] = None, - user_name: Optional[str] = None, - access_token: Optional[str] = None, - _debug: bool = False, - _transport: Optional[Transport] = None, - ): - self._config = ClientConfig.create( - config=config, - config_path=config_path, - server_url=server_url, - user_name=user_name, - access_token=access_token, - ) - assert self._config.server_url is not None - self._transport = ( - HttpxTransport( - server_url=self._config.server_url, - debug=_debug, - ) - if _transport is None - else _transport - ) - - @property - def config(self) -> ClientConfig: - return self._config - - def _repr_json_(self): - # noinspection PyProtectedMember - return self.config._repr_json_() - - def get_capabilities(self, **kwargs: Any) -> Capabilities: - """ - The landing page provides links to the: - * The OpenAPI-definition (no fixed path), - * The Conformance statements (path /conformance), - * The processes metadata (path /processes), - * The endpoint for job monitoring (path /jobs). - - For more information, see [OGC API — Processes — Part 1 - Section - 7.2](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_landing_page). - - Returns: - Capabilities: The landing page provides links to the API definition - (link relations `service-desc` and `service-doc`), - the Conformance declaration (path `/conformance`, - link relation `http://www.opengis.net/def/rel/ogc/1.0/conformance`), - and to other resources. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `500`: A server error occurred. - """ - return self._transport.call( - TransportArgs( - path="/", - method="get", - return_types={"200": Capabilities}, - error_types={"500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - def get_conformance(self, **kwargs: Any) -> ConformanceDeclaration: - """ - A list of all conformance classes, specified in a standard, that the - server conforms to. - - | Conformance class | URI | - |-----------|-------| - |Core|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/core| - |OGC Process Description|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/ogc-process-description| - |JSON|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/json| - |HTML|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/html| - |OpenAPI Specification 3.0|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/oas30| - |Job list|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/job-list| - |Callback|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/callback| - |Dismiss|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/dismiss| - - For more information, see [OGC API — Processes — Part 1 - Section 7.4](https://docs.ogc.org/is/18-062r2/18- - 062r2.html#sc_conformance_classes). - - - Returns: - ConformanceDeclaration: The URIs of all conformance classes supported - by the server. To support "generic" clients that want - to access multiple OGC API - Processes implementations - and - not "just" a specific API / server, the server declares - the conformance classes it implements and conforms to. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `500`: A server error occurred. - """ - return self._transport.call( - TransportArgs( - path="/conformance", - method="get", - return_types={"200": ConformanceDeclaration}, - error_types={"500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - def get_processes(self, **kwargs: Any) -> ProcessList: - """ - The list of processes contains a summary of each process the OGC API - - Processes offers, including the link to a more detailed description of - the process. - - For more information, see [OGC API — Processes — Part 1 - Section - 7.9](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_process_list). - - - Returns: - ProcessList: Information about the available processes - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - """ - return self._transport.call( - TransportArgs( - path="/processes", - method="get", - return_types={"200": ProcessList}, - extra_kwargs=kwargs, - ) - ) - - def get_process(self, process_id: str, **kwargs: Any) -> ProcessDescription: - """ - The process description contains information about inputs and outputs - and a link to the execution-endpoint for the process. The Core does not - mandate the use of a specific process description to specify the - interface of a process. That said, the Core requirements class makes the - following recommendation: - - Implementations **should** consider supporting the OGC process - description. - - For more information, see [OGC API — Processes — Part 1 - Section 7.10](https://docs.ogc.org/is/18-062r2/18- - 062r2.html#sc_process_description). - - Args: - process_id: - kwargs: Optional keyword arguments that may be - used by the underlying transport. - - Returns: - ProcessDescription: A process description. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - """ - return self._transport.call( - TransportArgs( - path="/processes/{processID}", - method="get", - path_params={"processID": process_id}, - return_types={"200": ProcessDescription}, - error_types={"404": ApiError}, - extra_kwargs=kwargs, - ) - ) - - def execute_process( - self, process_id: str, request: ProcessRequest, **kwargs: Any - ) -> JobInfo: - """ - Create a new job. - - For more information, see [OGC API — Processes — Part 1 - Section - 7.11](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_create_job). - - Args: - process_id: - kwargs: Optional keyword arguments that may be - used by the underlying transport. - request: Mandatory request JSON - - Returns: - JobInfo: Started asynchronous execution. Created job. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - - `500`: A server error occurred. - """ - return self._transport.call( - TransportArgs( - path="/processes/{processID}/execution", - method="post", - path_params={"processID": process_id}, - request=request, - return_types={"201": JobInfo}, - error_types={"404": ApiError, "500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - def get_jobs(self, **kwargs: Any) -> JobList: - """ - List available jobs. - - For more information, see [OGC API — Processes — Part 1 - Section 11](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_job_list). - - - Returns: - JobList: A list of jobs for this process. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - """ - return self._transport.call( - TransportArgs( - path="/jobs", - method="get", - return_types={"200": JobList}, - error_types={"404": ApiError}, - extra_kwargs=kwargs, - ) - ) - - def get_job(self, job_id: str, **kwargs: Any) -> JobInfo: - """ - Show the status of a job. - - For more information, see [OGC API — Processes — Part 1 - Section 7.12](https://docs.ogc.org/is/18-062r2/18- - 062r2.html#sc_retrieve_status_info). - - Args: - job_id: Local identifier of a job - kwargs: Optional keyword arguments that may be - used by the underlying transport. - - Returns: - JobInfo: The status of a job. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - - `500`: A server error occurred. - """ - return self._transport.call( - TransportArgs( - path="/jobs/{jobId}", - method="get", - path_params={"jobId": job_id}, - return_types={"200": JobInfo}, - error_types={"404": ApiError, "500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - def dismiss_job(self, job_id: str, **kwargs: Any) -> JobInfo: - """ - Cancel a job execution and removes it from the jobs list. - - For more information, see [OGC API — Processes — Part 1 - Section 13](https://docs.ogc.org/is/18-062r2/18-062r2.html#Dismiss). - - Args: - job_id: Local identifier of a job - kwargs: Optional keyword arguments that may be - used by the underlying transport. - - Returns: - JobInfo: Information about the job. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - - `500`: A server error occurred. - """ - return self._transport.call( - TransportArgs( - path="/jobs/{jobId}", - method="delete", - path_params={"jobId": job_id}, - return_types={"200": JobInfo}, - error_types={"404": ApiError, "500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - def get_job_results(self, job_id: str, **kwargs: Any) -> JobResults: - """ - List available results of a job. In case of a failure, list errors - instead. - - For more information, see [OGC API — Processes — Part 1 - Section 7.13](https://docs.ogc.org/is/18-062r2/18- - 062r2.html#sc_retrieve_job_results). - - Args: - job_id: Local identifier of a job - kwargs: Optional keyword arguments that may be - used by the underlying transport. - - Returns: - JobResults: The results of a job. - - Raises: - ClientError: If the call to the web service fails - with a status code != `2xx`. - - - `404`: The requested URI was not found. - - `500`: A server error occurred. - """ - return self._transport.call( - TransportArgs( - path="/jobs/{jobId}/results", - method="get", - path_params={"jobId": job_id}, - return_types={"200": JobResults}, - error_types={"404": ApiError, "500": ApiError}, - extra_kwargs=kwargs, - ) - ) - - def close(self): - """Close this client.""" - if self._transport is not None: - self._transport.close() diff --git a/s2gos-client/src/s2gos_client/api/client_mixin.py b/s2gos-client/src/s2gos_client/api/client_mixin.py deleted file mode 100644 index a84cc7e..0000000 --- a/s2gos-client/src/s2gos_client/api/client_mixin.py +++ /dev/null @@ -1,42 +0,0 @@ -from abc import ABC, abstractmethod -from typing import Any - -from s2gos_common.models import ProcessDescription -from s2gos_common.process import ExecutionRequest - - -# noinspection PyShadowingBuiltins -class ClientMixin(ABC): - """ - Extra methods for the API client (synchronous mode). - """ - - @abstractmethod - def get_process(self, process_id: str, **kwargs: Any) -> ProcessDescription: - """Will be overridden by the actual client class.""" - - def create_execution_request( - self, - process_id: str, - dotpath: bool = False, - ) -> ExecutionRequest: - """ - Create a template for an execution request - generated from the process description of the - given process identifier. - - Args: - process_id: The process identifier - dotpath: Whether to create dot-separated input - names for nested object values - - Returns: - The execution request template. - - Raises: - ClientError: if an error occurs - """ - process_description = self.get_process(process_id) - return ExecutionRequest.from_process_description( - process_description, dotpath=dotpath - ) diff --git a/s2gos-client/src/s2gos_client/api/config.py b/s2gos-client/src/s2gos_client/api/config.py deleted file mode 100644 index 8b08d47..0000000 --- a/s2gos-client/src/s2gos_client/api/config.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import os -from pathlib import Path -from typing import Any, Optional - -import yaml -from pydantic import BaseModel - -from .defaults import DEFAULT_CONFIG_PATH, DEFAULT_SERVER_URL - - -class ClientConfig(BaseModel): - """Client configuration. - - Args: - user_name: name of the registered S2GOS user - access_token: API access token - server_url: server API URL - """ - - user_name: Optional[str] = None - access_token: Optional[str] = None - server_url: Optional[str] = None - - def _repr_json_(self): - return self.model_dump(mode="json", by_alias=True), dict( - root="Client configuration:" - ) - - @classmethod - def create( - cls, - *, - config: Optional["ClientConfig"] = None, - config_path: Optional[Path | str] = None, - server_url: Optional[str] = None, - user_name: Optional[str] = None, - access_token: Optional[str] = None, - ) -> "ClientConfig": - config_dict = {"server_url": DEFAULT_SERVER_URL} - - # 1. from file - file_config = cls.from_file(config_path=config_path) - if file_config is not None: - config_dict.update(file_config.to_dict()) - - # 2. from env - env_config = cls.from_env() - if env_config is not None: - config_dict.update(env_config.to_dict()) - - # 3. from config - if config is not None: - config_dict.update(config.to_dict()) - - # 4. from args - args_config = ClientConfig( - user_name=user_name, - access_token=access_token, - server_url=server_url, - ) - config_dict.update(args_config.to_dict()) - - return ClientConfig(**config_dict) - - @classmethod - def from_file( - cls, config_path: Optional[str | Path] = None - ) -> Optional["ClientConfig"]: - config_path_: Path = cls.normalize_config_path(config_path) - if not config_path_.exists(): - return None - with config_path_.open("rt") as stream: - # Note, we may switch TOML - config_dict = yaml.safe_load(stream) - return ClientConfig(**config_dict) - - @classmethod - def from_env(cls) -> Optional["ClientConfig"]: - config_dict: dict[str, Any] = {} - for field_name, _field_info in ClientConfig.model_fields.items(): - env_var_name = "S2GOS_" + field_name.upper() - if env_var_name in os.environ: - config_dict[field_name] = os.environ[env_var_name] - return ClientConfig(**config_dict) if config_dict else None - - def write(self, config_path: Optional[str | Path] = None) -> Path: - config_path = self.normalize_config_path(config_path) - config_path.parent.mkdir(exist_ok=True) - with config_path.open("wt") as stream: - yaml.dump( - self.model_dump(mode="json", by_alias=True, exclude_none=True), stream - ) - return config_path - - @classmethod - def normalize_config_path(cls, config_path) -> Path: - return ( - config_path - if isinstance(config_path, Path) - else (Path(config_path) if config_path else DEFAULT_CONFIG_PATH) - ) - - def to_dict(self): - return self.model_dump( - mode="json", - by_alias=True, - exclude_none=True, - exclude_defaults=True, - exclude_unset=True, - ) diff --git a/s2gos-client/src/s2gos_client/api/defaults.py b/s2gos-client/src/s2gos_client/api/defaults.py deleted file mode 100644 index e373bed..0000000 --- a/s2gos-client/src/s2gos_client/api/defaults.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -# Important: this module shall have no s2gos dependencies - -from pathlib import Path -from typing import Final - -DEFAULT_USER_PATH: Final = Path("~").expanduser() / ".s2gos" -DEFAULT_CONFIG_PATH: Final = DEFAULT_USER_PATH / "config" - -DEFAULT_SERVER_URL: Final = "http://127.0.0.1:8008" diff --git a/s2gos-client/src/s2gos_client/api/exceptions.py b/s2gos-client/src/s2gos_client/api/exceptions.py deleted file mode 100644 index bb414ff..0000000 --- a/s2gos-client/src/s2gos_client/api/exceptions.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from s2gos_common.models import ApiError - - -class ClientError(Exception): - """Raised if a web API call failed. - - The failure can have several reasons such as - - - the request failed with a status code that is not 2xx, or - - the received JSON response is not parsable. - - Args: - message: The error message - api_error: The details describing the error that occurred on the server - or the details that describe a non-expected response from the server. - """ - - def __init__(self, message: str, api_error: ApiError): - super().__init__(message) - self.api_error = api_error diff --git a/s2gos-client/src/s2gos_client/api/ishell.py b/s2gos-client/src/s2gos_client/api/ishell.py deleted file mode 100644 index e856294..0000000 --- a/s2gos-client/src/s2gos_client/api/ishell.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import importlib.util -from typing import Any, Callable - -has_ishell = importlib.util.find_spec("IPython.core.interactiveshell") -exception_handler: Callable[[Any, Any, Any, Any], None] | None = None - -__all__ = ["has_ishell", "exception_handler"] - - -def _register_exception_handler() -> Callable[[Any, Any, Any, Any], None]: - from IPython.core.interactiveshell import InteractiveShell - from IPython.display import JSON, display - - from .exceptions import ClientError - - # noinspection PyUnusedLocal - def handle_exception( - self: InteractiveShell, exc_type, exc_value, tb, tb_offset=None - ): - if isinstance(exc_value, ClientError): - display( - JSON( - exc_value.api_error.model_dump(mode="json", exclude_none=True), - root="Client error", - expanded=True, - ) - ) - return None, None, None # prevents default traceback - - return None - - # Register handler for MyCustomError - InteractiveShell.instance().set_custom_exc((ClientError,), handle_exception) - return handle_exception - - -if has_ishell: - exception_handler = _register_exception_handler() diff --git a/s2gos-client/src/s2gos_client/api/transport/args.py b/s2gos-client/src/s2gos_client/api/transport/args.py deleted file mode 100644 index f379664..0000000 --- a/s2gos-client/src/s2gos_client/api/transport/args.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import inspect -from dataclasses import dataclass, field -from typing import Any, Literal, Optional -from urllib.parse import urljoin - -import pydantic -import uri_template -from pydantic import BaseModel - -from s2gos_client.api.exceptions import ClientError -from s2gos_common.models import ApiError - - -@dataclass -class TransportArgs: - path: str - method: Literal["get", "post", "put", "delete"] = "get" - path_params: dict[str, Any] = field(default_factory=dict) - query_params: dict[str, Any] = field(default_factory=dict) - request: BaseModel | None = None - return_types: dict[str, type | None] = field(default_factory=dict) - error_types: dict[str, type | None] = field(default_factory=dict) - extra_kwargs: dict[str, Any] = field(default_factory=dict) - - def get_url(self, server_url: str) -> str: - return urljoin(server_url, uri_template.expand(self.path, **self.path_params)) - - def get_json_for_request(self) -> Any: - request = self.request - return ( - request.model_dump( - mode="json", by_alias=True, exclude_none=True, exclude_defaults=True - ) - if isinstance(request, BaseModel) - else request - ) - - def get_response_for_status(self, status_code: int, json_data: Any): - status_key = str(status_code) - return_type = self.return_types.get(status_key) - if ( - return_type is not None - and inspect.isclass(return_type) - and issubclass(return_type, BaseModel) - ): - return return_type.model_validate(json_data) - else: - # TODO: warn or raise if we miss return_type - return json_data - - # noinspection PyMethodMayBeStatic - def get_exception_for_status( - self, - status_code: int, - message: str, - json_data: Optional[Any] = None, - ) -> ClientError: - status_key = str(status_code) - # Currently, all error types fall back to ApiError - _return_type = self.error_types.get(status_key) - if isinstance(json_data, dict): - try: - api_error = ApiError(**json_data) - except pydantic.ValidationError as e: - api_error = ApiError( - type="ValidationError", - title="Received invalid error details from API", - detail=f"{e}", - ) - else: - api_error = ApiError( - type="ValidationError", - title="Missing error details from API", - detail=f"JSON object expected, but got {type(json_data).__name__}", - ) - return ClientError(f"{message} (status {status_code})", api_error=api_error) diff --git a/s2gos-client/src/s2gos_client/api/transport/httpx.py b/s2gos-client/src/s2gos_client/api/transport/httpx.py deleted file mode 100644 index 4ab4dc9..0000000 --- a/s2gos-client/src/s2gos_client/api/transport/httpx.py +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import logging -from typing import Any - -import httpx - -from s2gos_client.api.exceptions import ClientError -from s2gos_common.models import ApiError - -from .args import TransportArgs -from .transport import AsyncTransport, Transport, TransportError - - -class HttpxTransport(Transport, AsyncTransport): - """A concrete web API transport based on the httpx package.""" - - def __init__(self, server_url: str, debug: bool = False): - self.server_url = server_url - self.debug = debug - self.sync_httpx: httpx.Client | None = None - self.async_httpx: httpx.AsyncClient | None = None - # Note, by default, we silence the httpx logger, however it may be - # useful to make that configurable - logging.getLogger("httpx").setLevel( - logging.DEBUG if debug else logging.CRITICAL - ) - - def call(self, args: TransportArgs) -> Any: - if self.sync_httpx is None: - self.sync_httpx = httpx.Client() - args_, kwargs_ = self._get_request_args(args) - try: - response = self.sync_httpx.request(*args_, **kwargs_) - except httpx.HTTPError as e: - raise TransportError(f"{e}") from e - return self._process_response(args, response) - - async def async_call(self, args: TransportArgs) -> Any: - if self.async_httpx is None: - self.async_httpx = httpx.AsyncClient() - args_, kwargs_ = self._get_request_args(args) - try: - response = await self.async_httpx.request(*args_, **kwargs_) - except httpx.HTTPError as e: - raise TransportError(f"{e}") from e - return self._process_response(args, response) - - def _get_request_args( - self, args: TransportArgs - ) -> tuple[tuple[str, str], dict[str, Any]]: - url = args.get_url(self.server_url) - request_json = args.get_json_for_request() - return (args.method.upper(), url), { - "params": args.query_params, - "json": request_json, - **args.extra_kwargs, - } - - # noinspection PyMethodMayBeStatic - def _process_response(self, args: TransportArgs, response: httpx.Response) -> Any: - try: - # Note, actually we should only do `response.json()` if JSON is expected, - # use args.return_types for this decision. - response_json = response.json() - except (ValueError, TypeError) as e: - raise ClientError( - f"{e}", - api_error=ApiError( - type=type(e).__name__, - title="Expected JSON response from API", - detail=f"{e}", - ), - ) from e - try: - response.raise_for_status() - return args.get_response_for_status(response.status_code, response_json) - except httpx.HTTPError as e: - raise args.get_exception_for_status( - response.status_code, f"{e}", response_json - ) from e - - def close(self): - if self.sync_httpx is not None: - assert self.async_httpx is None - self.sync_httpx.close() - self.sync_httpx = None - - async def async_close(self): - if self.async_httpx is not None: - assert self.sync_httpx is None - await self.async_httpx.aclose() - self.async_httpx = None diff --git a/s2gos-client/src/s2gos_client/api/transport/transport.py b/s2gos-client/src/s2gos_client/api/transport/transport.py deleted file mode 100644 index 049da9a..0000000 --- a/s2gos-client/src/s2gos_client/api/transport/transport.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from abc import ABC, abstractmethod -from typing import Any - -from .args import TransportArgs - - -class Transport(ABC): - """Abstraction of the transport that calls a web API in synchronous mode.""" - - @abstractmethod - def call(self, args: TransportArgs) -> Any: - """ - Synchronously call a web API with the given endpoint - `path`, `method`, `params`, etc. Then validate the response - and return an instance of one of the types given by - `return_types`. - - Args: - args: The transport arguments. - - Returns: - The response data of a successful web API call. - - Raises: - TransportError: If an attempt to reach the server failed. - """ - - def close(self): - """Closes this transport.""" - - -class AsyncTransport(ABC): - """Abstraction of the transport that calls a web API in asynchronous mode.""" - - @abstractmethod - async def async_call(self, args: TransportArgs) -> Any: - """ - Asynchronously call a web API with the given endpoint - `path`, `method`, `params`, etc. Then validate the response - and return an instance of one of the types given by - `return_types`. - - Args: - args: The transport arguments. - - Returns: - The response data of a successful web API call. - - Raises: - TransportError: If an attempt to reach the server failed. - """ - - async def async_close(self): - """Closes this transport.""" - - -class TransportError(Exception): - """Raised if an attempt to reach the server failed.""" diff --git a/s2gos-client/src/s2gos_client/gui/__init__.py b/s2gos-client/src/s2gos_client/cli.py similarity index 59% rename from s2gos-client/src/s2gos_client/gui/__init__.py rename to s2gos-client/src/s2gos_client/cli.py index 779cce7..3fc14ab 100644 --- a/s2gos-client/src/s2gos_client/gui/__init__.py +++ b/s2gos-client/src/s2gos_client/cli.py @@ -2,10 +2,13 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -import panel as pn +from cuiman.cli import get_cli -from .client import Client +cli = get_cli("s2gos-client") -__all__ = ["Client"] +__all__ = [ + "cli", +] -pn.extension("ipywidgets", "tabulator", notifications=True) +if __name__ == "__main__": + cli() diff --git a/s2gos-client/src/s2gos_client/cli/cli.py b/s2gos-client/src/s2gos_client/cli/cli.py deleted file mode 100644 index c786d1f..0000000 --- a/s2gos-client/src/s2gos_client/cli/cli.py +++ /dev/null @@ -1,348 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Annotated, Final, Optional - -import typer.core - -from s2gos_client.cli.output import OutputFormat -from s2gos_common.util.cli.group import AliasedGroup -from s2gos_common.util.cli.parameters import ( - DOT_PATH_OPTION, - PROCESS_ID_ARGUMENT, - REQUEST_FILE_OPTION, - REQUEST_INPUT_OPTION, - REQUEST_SUBSCRIBER_OPTION, -) - -SERVICE_NAME = "S2GOS service" - -CLI_NAME = "s2gos-client" -CLI_HELP = """ -`{app_name}` is the client shell tool for the {service_name}. - -The tool can be used to get the available processes, get process details, -execute processes, and manage the jobs originating from the latter. -It herewith resembles the functionality of the OGC API Processes - Part 1. - -You can use shorter command name aliases, e.g., use command name `vr` -for `validate-request`, or `lp` for `list-processes`. - -The tool's exit codes are as follows: - -- `0` - normal exit -- `1` - user errors, argument errors -- `2` - remote API errors -- `3` - local network transport errors - -If the --traceback flag is set, the original Python exception traceback -will be shown and the exit code will always be `1`. -Otherwise, only the error message is shown. -""".format(app_name=CLI_NAME, service_name=SERVICE_NAME) - -DEFAULT_OUTPUT_FORMAT: Final = OutputFormat.yaml - -CONFIG_OPTION = typer.Option( - "--config", - "-c", - help="Client configuration file.", - metavar="PATH", -) - -FORMAT_OPTION = typer.Option( - ..., - "--format", - "-f", - show_choices=True, - help="Output format.", - # metavar="FORMAT", -) - -JOB_ID_ARGUMENT = typer.Argument( - help="Job identifier.", -) - -cli = typer.Typer( - name=CLI_NAME, - cls=AliasedGroup, - help=CLI_HELP, - invoke_without_command=True, - context_settings={}, - # rich_markup_mode="rich", # doesn't work - # # but should, see https://github.com/fastapi/typer/discussions/818 - # no_args_is_help=True, # check: it shows empty error msg -) - - -@cli.callback() -def main( - ctx: typer.Context, - version_: Annotated[ - bool, typer.Option("--version", help="Show version and exit.") - ] = False, - traceback: Annotated[ - bool, - typer.Option( - "--traceback", "--tb", help="Show server exception traceback, if any." - ), - ] = False, - # add global options here... - # verbose: bool = typer.Option(False, "--verbose", "-v", - # help="Verbose output"), -): - if version_: - from importlib.metadata import version - - typer.echo(version("s2gos-client")) - return - - def get_client(config_path: str | None): - # defer importing - from s2gos_client import Client - from s2gos_client.cli.config import get_config - - config = get_config(config_path) - return Client(config=config) - - ctx.ensure_object(dict) - # ONLY set context values if they haven't already been set, - # for example, by a test - for k, v in dict( - get_client=get_client, - traceback=traceback, - # add global options here... - # verbose=verbose, - ).items(): - if k not in ctx.obj: - ctx.obj[k] = v - - -@cli.command() -def configure( - user_name: Optional[str] = typer.Option( - None, - "--user", - "-u", - help="Your user name.", - ), - access_token: Optional[str] = typer.Option( - None, - "--token", - "-t", - help="Your personal access token.", - ), - server_url: Optional[str] = typer.Option( - None, - "--server", - "-s", - help=f"The {SERVICE_NAME} API URL.", - ), - config_file: Annotated[Optional[str], CONFIG_OPTION] = None, -): - """Configure the client tool.""" - from .config import configure_client - - config_path = configure_client( - user_name=user_name, - access_token=access_token, - server_url=server_url, - config_path=config_file, - ) - typer.echo(f"Client configuration written to {config_path}") - - -@cli.command() -def list_processes( - ctx: typer.Context, - config_file: Annotated[Optional[str], CONFIG_OPTION] = None, - output_format: Annotated[OutputFormat, FORMAT_OPTION] = DEFAULT_OUTPUT_FORMAT, -): - """List available processes.""" - from .client import use_client - from .output import get_renderer, output - - with use_client(ctx, config_file) as client: - process_list = client.get_processes() - output(get_renderer(output_format).render_process_list(process_list)) - - -@cli.command() -def get_process( - ctx: typer.Context, - process_id: Annotated[str, PROCESS_ID_ARGUMENT], - config_file: Annotated[Optional[str], CONFIG_OPTION] = None, - output_format: Annotated[OutputFormat, FORMAT_OPTION] = DEFAULT_OUTPUT_FORMAT, -): - """Get process details.""" - from .client import use_client - from .output import get_renderer, output - - with use_client(ctx, config_file) as client: - process_description = client.get_process(process_id) - output(get_renderer(output_format).render_process_description(process_description)) - - -@cli.command() -def create_request( - ctx: typer.Context, - process_id: Annotated[Optional[str], PROCESS_ID_ARGUMENT] = None, - dotpath: Annotated[bool, DOT_PATH_OPTION] = False, - config_file: Annotated[Optional[str], CONFIG_OPTION] = None, - output_format: Annotated[OutputFormat, FORMAT_OPTION] = DEFAULT_OUTPUT_FORMAT, -): - """ - Create an execution request (template) for a given process. - - The generated template comprises generated default values for all inputs. - Note that they might not necessarily be valid. - The generated template request may serve as a starting point for the actual, - valid execution request. - """ - from .client import use_client - from .output import get_renderer, output - - with use_client(ctx, config_file) as client: - request = client.create_execution_request(process_id, dotpath=dotpath) - - output(get_renderer(output_format).render_execution_request_valid(request)) - - -@cli.command() -def validate_request( - process_id: Annotated[Optional[str], PROCESS_ID_ARGUMENT] = None, - dotpath: Annotated[bool, DOT_PATH_OPTION] = False, - request_inputs: Annotated[Optional[list[str]], REQUEST_INPUT_OPTION] = None, - request_file: Annotated[Optional[str], REQUEST_FILE_OPTION] = None, - output_format: Annotated[OutputFormat, FORMAT_OPTION] = DEFAULT_OUTPUT_FORMAT, -): - """ - Validate a process execution request. - - The execution request to be validated may be read from a file given - by `--request`, or from `stdin`, or from the `process_id` argument - with zero, one, or more `--input` (or `-i`) options. - - The `process_id` argument and any given `--input` options will override - settings with the same name found in the given request file or `stdin`, if any. - """ - from s2gos_common.process.request import ExecutionRequest - - from .output import get_renderer, output - - request = ExecutionRequest.create( - process_id=process_id, - dotpath=dotpath, - inputs=request_inputs, - request_path=request_file, - ) - output(get_renderer(output_format).render_execution_request_valid(request)) - - -@cli.command() -def execute_process( - ctx: typer.Context, - process_id: Annotated[Optional[str], PROCESS_ID_ARGUMENT] = None, - dotpath: Annotated[bool, DOT_PATH_OPTION] = False, - request_inputs: Annotated[Optional[list[str]], REQUEST_INPUT_OPTION] = None, - request_subscribers: Annotated[ - Optional[list[str]], REQUEST_SUBSCRIBER_OPTION - ] = None, - request_file: Annotated[Optional[str], REQUEST_FILE_OPTION] = None, - config_file: Annotated[Optional[str], CONFIG_OPTION] = None, - output_format: Annotated[OutputFormat, FORMAT_OPTION] = DEFAULT_OUTPUT_FORMAT, -): - """ - Execute a process in asynchronous mode. - - The execution request to be submitted may be read from a file given - by `--request`, or from `stdin`, or from the `process_id` argument - with zero, one, or more `--input` (or `-i`) options. - - The `process_id` argument and any given `--input` options will override - settings with same name found in the given request file or `stdin`, if any. - """ - from s2gos_common.process.request import ExecutionRequest - - from .client import use_client - from .output import get_renderer, output - - request = ExecutionRequest.create( - process_id=process_id, - dotpath=dotpath, - inputs=request_inputs, - subscribers=request_subscribers, - request_path=request_file, - ) - with use_client(ctx, config_file) as client: - job = client.execute_process( - process_id=request.process_id, request=request.to_process_request() - ) - output(get_renderer(output_format).render_job_info(job)) - - -@cli.command() -def list_jobs( - ctx: typer.Context, - config_file: Annotated[Optional[str], CONFIG_OPTION] = None, - output_format: Annotated[OutputFormat, FORMAT_OPTION] = DEFAULT_OUTPUT_FORMAT, -): - """List all jobs.""" - from .client import use_client - from .output import get_renderer, output - - with use_client(ctx, config_file) as client: - job_list = client.get_jobs() - output(get_renderer(output_format).render_job_list(job_list)) - - -@cli.command() -def get_job( - ctx: typer.Context, - job_id: Annotated[str, JOB_ID_ARGUMENT], - config_file: Annotated[Optional[str], CONFIG_OPTION] = None, - output_format: Annotated[OutputFormat, FORMAT_OPTION] = DEFAULT_OUTPUT_FORMAT, -): - """Get job details.""" - from .client import use_client - from .output import get_renderer, output - - with use_client(ctx, config_file) as client: - job = client.get_job(job_id) - output(get_renderer(output_format).render_job_info(job)) - - -@cli.command() -def dismiss_job( - ctx: typer.Context, - job_id: Annotated[str, JOB_ID_ARGUMENT], - config_file: Annotated[Optional[str], CONFIG_OPTION] = None, - output_format: Annotated[OutputFormat, FORMAT_OPTION] = DEFAULT_OUTPUT_FORMAT, -): - """Cancel a running or delete a finished job.""" - from .client import use_client - from .output import get_renderer, output - - with use_client(ctx, config_file) as client: - job = client.dismiss_job(job_id) - output(get_renderer(output_format).render_job_info(job)) - - -@cli.command() -def get_job_results( - ctx: typer.Context, - job_id: Annotated[str, JOB_ID_ARGUMENT], - config_file: Annotated[Optional[str], CONFIG_OPTION] = None, - output_format: Annotated[OutputFormat, FORMAT_OPTION] = DEFAULT_OUTPUT_FORMAT, -): - """Get job results.""" - from .client import use_client - from .output import get_renderer, output - - with use_client(ctx, config_file) as client: - job_results = client.get_job_results(job_id) - output(get_renderer(output_format).render_job_results(job_results)) - - -if __name__ == "__main__": # pragma: no cover - cli() diff --git a/s2gos-client/src/s2gos_client/cli/client.py b/s2gos-client/src/s2gos_client/cli/client.py deleted file mode 100644 index 200c139..0000000 --- a/s2gos-client/src/s2gos_client/cli/client.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from types import TracebackType -from typing import Callable, Literal, Optional, TypeAlias - -import typer - -from s2gos_client.api.client import Client -from s2gos_client.api.exceptions import ClientError -from s2gos_client.api.transport import TransportError - -GetClient: TypeAlias = Callable[[str | None], Client] - - -def use_client(ctx: typer.Context, config_file: str | None) -> "UseClient": - """ - Context manager - """ - return UseClient(ctx, config_file) - - -class UseClient: - def __init__(self, ctx: typer.Context, config_file: str | None): - self.ctx = ctx - self.config_file = config_file - self.client: Client | None = None - - def __enter__(self): - _get_client: GetClient = self.ctx.obj["get_client"] - self.client = _get_client(self.config_file) - return self.client - - def __exit__( - self, - exc_type: Optional[type[BaseException]], - exc_value: Optional[BaseException], - exc_tb: Optional[TracebackType], - ) -> Literal[False]: - if self.client is not None: - self.client.close() - self.client = None - show_traceback = self.ctx.obj.get("traceback", False) - if isinstance(exc_value, ClientError): - # Note for the following it may be a good idea to - # to use rich.traceback for comprehensive output - client_error: ClientError = exc_value - api_error = client_error.api_error - message_lines = [ - f"❌ Error: {client_error}", - "Server-side error details:", - f" title: {api_error.title}", - f" status: {api_error.status}", - f" type: {api_error.type}", - f" detail: {api_error.detail}", - ] - if api_error.traceback and show_traceback: - message_lines.append(" traceback:") - message_lines.extend(api_error.traceback) - typer.echo("\n".join(message_lines)) - if not show_traceback: - raise typer.Exit(code=2) - elif isinstance(exc_value, TransportError): - typer.echo(f"❌ Transport error: {exc_value}") - if not show_traceback: - raise typer.Exit(code=3) - - return False # propagate exception diff --git a/s2gos-client/src/s2gos_client/cli/config.py b/s2gos-client/src/s2gos_client/cli/config.py deleted file mode 100644 index 87882ce..0000000 --- a/s2gos-client/src/s2gos_client/cli/config.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import os -from pathlib import Path - -import click -import typer - -from s2gos_client.api.config import ClientConfig -from s2gos_client.api.defaults import DEFAULT_SERVER_URL - - -def get_config(config_path: Path | str | None) -> ClientConfig: - file_config = ClientConfig.from_file(config_path=config_path) - if file_config is None: - if config_path is None: - raise click.ClickException( - "The client tool has not yet been configured;" - " please use the 'configure' command to set it up." - ) - else: - raise click.ClickException( - f"Configuration file {config_path} not found or empty." - ) - return ClientConfig.create(config=file_config) - - -def configure_client( - user_name: str | None = None, - access_token: str | None = None, - server_url: str | None = None, - config_path: Path | str | None = None, -) -> Path: - config = ClientConfig.create(config_path=config_path) - if not user_name: - user_name = typer.prompt( - "User name", - default=( - (config and config.user_name) - or os.environ.get("USER", os.environ.get("USERNAME")) - ), - ) - if not access_token: - prev_access_token = config and config.access_token - _access_token = typer.prompt( - "Access token", - type=str, - hide_input=True, - default="*****" if prev_access_token else None, - ) - if _access_token == "*****" and prev_access_token: - access_token = prev_access_token - else: - access_token = _access_token - if not server_url: - server_url = typer.prompt( - "Server URL", - default=(config and config.server_url) or DEFAULT_SERVER_URL, - ) - return ClientConfig( - user_name=user_name, access_token=access_token, server_url=server_url - ).write(config_path=config_path) diff --git a/s2gos-client/src/s2gos_client/cli/output.py b/s2gos-client/src/s2gos_client/cli/output.py deleted file mode 100644 index 9f838e7..0000000 --- a/s2gos-client/src/s2gos_client/cli/output.py +++ /dev/null @@ -1,187 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from abc import ABC, abstractmethod -from enum import Enum -from typing import Any, Callable, Literal - -import pydantic -import typer - -from s2gos_common.models import ( - JobInfo, - JobList, - JobResults, - ProcessDescription, - ProcessList, -) -from s2gos_common.process.request import ExecutionRequest - - -class OutputFormat(str, Enum): - simple = "simple" - json = "json" - yaml = "yaml" - - -def output(message: str): - typer.echo(message) - - -def get_renderer( - output_format: OutputFormat, verbose: bool = False -) -> "OutputRenderer": - renderers: dict[OutputFormat, Callable[[bool], OutputRenderer]] = { - OutputFormat.simple: SimpleOutputRenderer, - OutputFormat.json: JsonOutputRenderer, - OutputFormat.yaml: YamlOutputRenderer, - } - return renderers[output_format](verbose) - - -class OutputRenderer(ABC): - @abstractmethod - def render_process_list(self, process_list: ProcessList) -> str: - """Render a process list.""" - - @abstractmethod - def render_process_description( - self, process_description: ProcessDescription - ) -> str: - """Render a process description.""" - - @abstractmethod - def render_execution_request_valid( - self, execution_request: ExecutionRequest - ) -> str: - """Render an execution request is valid.""" - - @abstractmethod - def render_job_list(self, job_list: JobList) -> str: - """Render a job list.""" - - @abstractmethod - def render_job_info(self, job: JobInfo) -> str: - """Render a job.""" - - @abstractmethod - def render_job_results(self, job_results: JobResults) -> str: - """Render a job results.""" - - def _render_base_model( - self, - base_model: pydantic.BaseModel, - format_name: Literal["json", "yaml"] = "yaml", - ) -> str: - serialized_value = self._serialize_model(base_model) - if format_name == "yaml": - import yaml - - text_value = yaml.safe_dump(serialized_value, indent=2) - else: - import json - - text_value = json.dumps(serialized_value, indent=2) - return text_value - - @classmethod - def _serialize_model(cls, base_model: pydantic.BaseModel) -> Any: - return base_model.model_dump( - mode="json", - by_alias=True, - exclude_defaults=True, - exclude_none=True, - exclude_unset=True, - ) - - -class SimpleOutputRenderer(OutputRenderer): - def __init__(self, verbose: bool): - self.verbose = verbose - - def render_process_list(self, process_list: ProcessList) -> str: - if not process_list.processes: - return "No processes available." - else: - return "\n".join( - f"{i + 1}: {process.id} - {process.title}" - for i, process in enumerate(process_list.processes) - ) - - def render_process_description( - self, process_description: ProcessDescription - ) -> str: - return self._render_base_model(process_description) - - def render_execution_request_valid( - self, execution_request: ExecutionRequest - ) -> str: - return "Execution request is valid:\n" + self._render_base_model( - execution_request - ) - - def render_job_list(self, job_list: JobList) -> str: - if not job_list.jobs: - return "No jobs available." - else: - return "\n".join( - f"{i + 1}: {job.jobID} - {job.status} - {job.progress} - {job.message}" - for i, job in enumerate(job_list.jobs) - ) - - def render_job_info(self, job: JobInfo) -> str: - return "\n".join( - [ - f"Job ID: {job.jobID}", - f"Process ID: {job.processID}", - f"Status: {job.status}", - f"Progress: {job.progress}", - f"Message: {job.message}", - f"Created at: {job.created}", - f"Started at: {job.started}", - f"Updated at: {job.updated}", - f"Ended at: {job.finished}", - ] - ) - - def render_job_results(self, job_results: JobResults) -> str: - return self._render_base_model(job_results) - - -class StructuredOutputRenderer(OutputRenderer): - def __init__(self, format_name: Literal["json", "yaml"], verbose: bool): - self.format_name = format_name - self.verbose = verbose - - def render_process_list(self, process_list: ProcessList) -> str: - return self._render_base_model(process_list, self.format_name) - - def render_process_description( - self, process_description: ProcessDescription - ) -> str: - return self._render_base_model(process_description, self.format_name) - - def render_execution_request_valid( - self, execution_request: ExecutionRequest - ) -> str: - return self._render_base_model(execution_request, self.format_name) - - def render_job_list(self, job_list: JobList) -> str: - return self._render_base_model(job_list, self.format_name) - - def render_job_info(self, job: JobInfo) -> str: - return self._render_base_model(job, self.format_name) - - def render_job_results(self, job_results: JobResults) -> str: - return self._render_base_model(job_results, self.format_name) - - -class YamlOutputRenderer(StructuredOutputRenderer): - def __init__(self, verbose: bool): - super().__init__("yaml", verbose) - - -class JsonOutputRenderer(StructuredOutputRenderer): - def __init__(self, verbose: bool): - super().__init__("json", verbose) diff --git a/s2gos-client/src/s2gos_client/cli/__init__.py b/s2gos-client/src/s2gos_client/gui.py similarity index 76% rename from s2gos-client/src/s2gos_client/cli/__init__.py rename to s2gos-client/src/s2gos_client/gui.py index 54780e5..eea6e26 100644 --- a/s2gos-client/src/s2gos_client/cli/__init__.py +++ b/s2gos-client/src/s2gos_client/gui.py @@ -2,6 +2,8 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -from .cli import cli +from cuiman.gui import Client -__all__ = ["cli"] +__all__ = [ + "Client", +] diff --git a/s2gos-client/src/s2gos_client/gui/client.py b/s2gos-client/src/s2gos_client/gui/client.py deleted file mode 100644 index 45d8ffa..0000000 --- a/s2gos-client/src/s2gos_client/gui/client.py +++ /dev/null @@ -1,156 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import threading -import time -from typing import Optional - -from s2gos_client.api.client import Client as ApiClient -from s2gos_client.api.exceptions import ClientError -from s2gos_client.api.transport import Transport -from s2gos_common.models import JobInfo, ProcessList - -from .job_info_panel import JobInfoPanel -from .jobs_observer import JobsObserver -from .jobs_panel import JobsPanel -from .main_panel import MainPanel - - -class Client(ApiClient): - def __init__( - self, - *, - update_interval: float = 2.0, - _transport: Optional[Transport] = None, - **config, - ): - super().__init__(_transport=_transport, **config) - self._jobs: dict[str, JobInfo] = {} - self._jobs_observers: list[JobsObserver] = [] - self._update_interval = update_interval - self._update_thread: Optional[threading.Thread] = None - # Panels - self._main_panel: Optional[MainPanel] = None - self._jobs_panel: Optional[JobsPanel] = None - self._job_info_panels: dict[str, JobInfoPanel] = {} - - def _reset_state(self): - self._jobs = {} - self._jobs_observers = [] - self._update_thread = None - # Panels - self._main_panel = None - self._jobs_panel = None - self._job_info_panels = {} - - def show(self) -> MainPanel: - if self._main_panel is None: - self._main_panel = MainPanel( - *self._get_processes(), - on_get_process=self.get_process, - on_execute_process=self.execute_process, - ) - # noinspection PyTypeChecker - self._jobs_observers.append(self._main_panel) - - self._ensure_update_thread_is_running() - - return self._main_panel - - def show_jobs(self) -> JobsPanel: - if self._jobs_panel is None: - self._jobs_panel = JobsPanel( - on_cancel_job=self._cancel_job, - on_delete_job=self._delete_job, - on_restart_job=self._restart_job, - on_get_job_results=self.get_job_results, - ) - # noinspection PyTypeChecker - self._jobs_observers.append(self._jobs_panel) - - self._ensure_update_thread_is_running() - - return self._jobs_panel - - def show_job(self, job_id: str) -> JobInfoPanel: - job_info_panel = self._job_info_panels.get(job_id) - if job_info_panel is None: - job_info_panel = JobInfoPanel() - job_info_panel.job_info = self._jobs.get(job_id) - self._job_info_panels[job_id] = job_info_panel - # noinspection PyTypeChecker - self._jobs_observers.append(job_info_panel) - - self._ensure_update_thread_is_running() - - return job_info_panel - - def close(self): - self._reset_state() - super().close() - - def _cancel_job(self, job_id: str): - return self.dismiss_job(job_id) - - def _delete_job(self, job_id: str): - return self.dismiss_job(job_id) - - # noinspection PyMethodMayBeStatic - def _restart_job(self, _job_id: str): - # TODO: implement job restart - print("Not implemented.") - - def __delete__(self, instance): - self._reset_state() - - def _ensure_update_thread_is_running(self): - if self._update_thread is None or not self._update_thread.is_alive(): - self._update_thread = threading.Thread( - target=self._run_jobs_updater, daemon=True - ) - self._update_thread.start() - - def _run_jobs_updater(self): - while self._update_thread is not None: - if self._jobs_observers: - self._update_jobs() - time.sleep(self._update_interval) - - def _update_jobs(self): - try: - job_list = self.get_jobs() - except ClientError as e: - for jobs_observer in self._jobs_observers: - jobs_observer.on_job_list_error(e) - return - - old_jobs = self._jobs - new_jobs = {job.jobID: job for job in job_list.jobs} - - added_jobs = [job for job_id, job in new_jobs.items() if job_id not in old_jobs] - changed_jobs = [ - job - for job_id, job in new_jobs.items() - if job_id in old_jobs and job != old_jobs[job_id] - ] - removed_jobs = [ - job for job_id, job in old_jobs.items() if job_id not in new_jobs - ] - - if added_jobs or changed_jobs or removed_jobs: - for jobs_observer in self._jobs_observers: - for job in added_jobs: - jobs_observer.on_job_added(job) - for job in changed_jobs: - jobs_observer.on_job_changed(job) - for job in removed_jobs: - jobs_observer.on_job_removed(job) - jobs_observer.on_job_list_changed(job_list) - self._jobs = new_jobs - - def _get_processes(self) -> tuple[ProcessList, ClientError | None]: - try: - return self.get_processes(), None - except ClientError as e: - return ProcessList(processes=[], links=[]), e diff --git a/s2gos-client/src/s2gos_client/gui/component/__init__.py b/s2gos-client/src/s2gos_client/gui/component/__init__.py deleted file mode 100644 index 1b5f3cc..0000000 --- a/s2gos-client/src/s2gos_client/gui/component/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from .component import Component, WidgetComponent -from .container import ComponentContainer -from .factory import ComponentFactory, ComponentFactoryBase -from .json import ( - JsonCodec, - JsonDateCodec, - JsonIdentityCodec, - JsonSchemaDict, - JsonType, - JsonValue, -) -from .registry import ComponentFactoryRegistry - -__all__ = [ - "Component", - "ComponentContainer", - "ComponentFactory", - "ComponentFactoryBase", - "ComponentFactoryRegistry", - "JsonCodec", - "JsonDateCodec", - "JsonIdentityCodec", - "JsonSchemaDict", - "JsonType", - "JsonValue", - "WidgetComponent", -] diff --git a/s2gos-client/src/s2gos_client/gui/component/bbox.py b/s2gos-client/src/s2gos_client/gui/component/bbox.py deleted file mode 100644 index eab5bd0..0000000 --- a/s2gos-client/src/s2gos_client/gui/component/bbox.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import panel as pn -import param -from ipyleaflet import DrawControl, GeoJSON, Map - - -class BboxSelector(pn.viewable.Viewer): - value = param.List( - bounds=(4, 4), - default=None, - doc="Bounding box as [min_lon, min_lat, max_lon, max_lat]", - ) - - def __init__(self, center=(0, 0), zoom=2, **params): - # noinspection PyArgumentList - super().__init__(**params) - - # Set up the draw control - draw_control = DrawControl(rectangle={"shapeOptions": {"color": "#0000FF"}}) - draw_control.rectangle = {"shapeOptions": {"color": "#0000FF"}} - draw_control.circle = {} - draw_control.polyline = {} - draw_control.polygon = {} - draw_control.point = {} - draw_control.on_draw(self._handle_draw) - - # Create the map - self.map = Map(center=center, zoom=zoom, scroll_wheel_zoom=True) - self.map.add(draw_control) - - # Leaflet map as ipy-widget - map_widget = pn.pane.IPyWidget(self.map, width=512) - - # Displayed value as text for feedback - value_display = pn.widgets.StaticText( - name="Selected bbox", value=str(self.value) - ) - - self._panel = pn.Column(map_widget, value_display) - self._value_display = value_display - - def __panel__(self): - return self._panel - - def _handle_draw(self, target: DrawControl, action: str, geo_json: dict): - if action == "created" and geo_json["geometry"]["type"] == "Polygon": - target.clear() - - coords = geo_json["geometry"]["coordinates"][0] - lons = [c[0] for c in coords] - lats = [c[1] for c in coords] - min_lon, max_lon = min(lons), max(lons) - min_lat, max_lat = min(lats), max(lats) - self.value = [min_lon, min_lat, max_lon, max_lat] - self._value_display.value = str(self.value) - - for layer in self.map.layers: - if layer.name == "user": - self.map.remove(layer) - break - user_layer = GeoJSON(name="user", data=geo_json) - self.map.add(user_layer) diff --git a/s2gos-client/src/s2gos_client/gui/component/component.py b/s2gos-client/src/s2gos_client/gui/component/component.py deleted file mode 100644 index e1b57d8..0000000 --- a/s2gos-client/src/s2gos_client/gui/component/component.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Any, Callable, Optional - -import panel as pn -import param - -from .json import ( - JsonCodec, - JsonIdentityCodec, - JsonValue, -) - - -class Component: - def __init__( - self, - viewable: param.Parameterized, - json_codec: Optional[JsonCodec] = None, - ): - super().__init__() - self.viewable = viewable - self.json_codec = JsonIdentityCodec() if json_codec is None else json_codec - - def get_json_value(self) -> Any: - """Get the viewable's value as a json value.""" - return self.json_codec.to_json(self.get_value()) - - def set_json_value(self, json_value: JsonValue): - """Sets the viewable's value from a json value.""" - self.set_value(self.json_codec.from_json(json_value)) - - def get_value(self) -> Any: - """Get the viewable's value.""" - raise NotImplementedError - - def set_value(self, value: Any): - """Sets the viewable's value.""" - raise NotImplementedError - - def watch_value(self, callback: Callable[[Any], Any]): - """Watch for value changes in the viewable.""" - raise NotImplementedError - - -class WidgetComponent(Component): - def __init__(self, widget: pn.widgets.Widget, json_codec: JsonCodec | None = None): - super().__init__(widget, json_codec=json_codec) - - @property - def widget(self) -> pn.widgets.Widget: - # noinspection PyTypeChecker - return self.viewable - - def get_value(self) -> Any: - """Get the viewable's value.""" - return self.widget.value - - def set_value(self, value: Any): - """Sets the viewable's value.""" - self.widget.value = value - - def watch_value(self, callback: Callable[[Any], Any]): - """Watch for value changes in the viewable.""" - self.widget.param.watch(callback, "value") diff --git a/s2gos-client/src/s2gos_client/gui/component/container.py b/s2gos-client/src/s2gos_client/gui/component/container.py deleted file mode 100644 index 843faee..0000000 --- a/s2gos-client/src/s2gos_client/gui/component/container.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import warnings -from dataclasses import dataclass -from typing import Any, Callable, Literal, TypeAlias - -import param - -from s2gos_common.models import InputDescription, Schema - -from .component import Component -from .impl import register_all -from .json import JsonSchemaDict, JsonValue -from .registry import ComponentFactoryRegistry - -FailMode: TypeAlias = Literal["raise", "warn", "ignore"] - - -class ComponentContainer: - registry = ComponentFactoryRegistry() - - @dataclass - class Item: - schema: JsonSchemaDict - # TODO: check if we need value here - value: JsonValue - component: Component - - @classmethod - def from_input_descriptions( - cls, - input_descriptions: dict[str, InputDescription], - json_values: dict[str, JsonValue], - fail_mode: FailMode = "warn", - ) -> "ComponentContainer": - schemas: dict[str, JsonSchemaDict] = {} - for k, v in input_descriptions.items(): - schema = _get_schema_from_input_description(v) - if schema is not None: - schemas[k] = schema - elif fail_mode != "ignore": - msg = f"Failed getting usable JSON schema for input {k!r}" - if fail_mode == "warn": - warnings.warn(msg) - else: - raise ValueError(msg) - - return cls(schemas, json_values, fail_mode=fail_mode) - - def __init__( - self, - schemas: dict[str, JsonSchemaDict], - json_values: dict[str, JsonValue], - fail_mode: Literal["raise", "warn", "ignore"] = "warn", - ): - self._entries: dict[str, ComponentContainer.Item] = {} - for name, schema in schemas.items(): - factory = self.registry.find_factory(schema) - if factory is not None: - value: JsonValue = json_values.get(name, schema.get("default")) - title: str = schema.get("title") or _get_title_from_name(name) # type: ignore[assignment] - component = factory.create_component(value, title, schema) - # TODO: check if we need this - component.watch_value(self._get_on_value_changed(name, component)) - self._entries[name] = ComponentContainer.Item(schema, value, component) - elif fail_mode != "ignore": - msg = ( - f"Failed creating component for input {name!r}" - f" with schema {schema!r}" - ) - if fail_mode == "raise": - raise ValueError(msg) - warnings.warn(msg) - - def get_json_values(self): - """Get component values as JSON values.""" - return { - name: entry.component.get_json_value() - for name, entry in self._entries.items() - } - - def set_json_values(self, json_values: dict[str, JsonValue]): - """Set component values from JSON values.""" - return { - name: entry.component.set_json_value(json_values[name]) - for name, entry in self._entries.items() - if name in json_values - } - - def get_components(self) -> list[Component]: - return [entry.component for entry in self._entries.values()] - - def get_viewables(self) -> list[param.Parameterized]: - return [entry.component.viewable for entry in self._entries.values()] - - def _get_on_value_changed(self, name: str, component: Component) -> Callable: - def on_value_changed(event: Any): - json_value = component.json_codec.to_json(event.new) - self._entries[name].value = json_value - - return on_value_changed - - -register_all(ComponentContainer.registry) - - -def _get_title_from_name(name: str) -> str: - return name.capitalize().replace("-", " ").replace("_", " ") - - -def _get_schema_from_input_description( - input_description: InputDescription, -) -> JsonSchemaDict | None: - v = input_description - if not isinstance(v.schema_, Schema): - return None - schema = v.schema_.model_dump( - mode="json", exclude_defaults=True, exclude_none=True, by_alias=True - ) - is_scalar = v.minOccurs in (0, 1) and v.maxOccurs in (None, 1) - if not is_scalar: - schema = { - "type": "array", - "items": schema, - "minItems": (v.minOccurs if isinstance(v.minOccurs, int) else None), - "maxItems": (v.maxOccurs if isinstance(v.maxOccurs, int) else None), - } - if v.title: - schema["title"] = v.title - if v.description: - schema["description"] = v.description - return schema diff --git a/s2gos-client/src/s2gos_client/gui/component/factory.py b/s2gos-client/src/s2gos_client/gui/component/factory.py deleted file mode 100644 index a89f665..0000000 --- a/s2gos-client/src/s2gos_client/gui/component/factory.py +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import inspect -from abc import ABC, abstractmethod -from types import FunctionType -from typing import TYPE_CHECKING, Literal - -from .component import Component -from .json import JSON_TYPE_NAMES, JsonSchemaDict, JsonType, JsonValue - -if TYPE_CHECKING: - from .registry import ComponentFactoryRegistry - - -class ComponentFactory(ABC): - """ - Factory for components. - Instances of this class are registered in a `ComponentFactoryRegistry` - using the combination of a JSON schema type and format - as registration key. - """ - - @abstractmethod - def create_component( - self, value: JsonValue, title: str, schema: JsonSchemaDict - ) -> Component: - """ - Create a new component from given JSON schema. - - Args: - value: the initial JSON input value, may be `None` - title: a component title - schema: the schema - - Returns: a component - """ - - @abstractmethod - def accept(self, schema: JsonSchemaDict) -> bool: - """ - Check, whether the components produced by this factory - can use the given schema. - """ - - -class ComponentFactoryBase(ComponentFactory, ABC): - """ - Base class for component factories that dedicated to JSON type and/or format. - """ - - type: JsonType | Literal["*"] | None = None - """ - Specifies the JSON type to use as a registry key. - The key `"*"` can be used for arbitrary types and requires - overriding the `accept` method by a suitable implementation - that recognizes the actual type in the schema. - The key `None` expects that a type must not be specified - in a given schema. - """ - - format: str | Literal["*"] | None = None - """ - Specifies the JSON type to use as a registry key. - The key `"*"` can be used for arbitrary types and requires - overriding the `accept` method by a suitable implementation - that recognizes the actual format in the schema. - The key `None` expects that a type must not be specified - in a given schema. - """ - - def __init__(self): - if self.type == "*" or self.format == "*": - if not _has_own_accept_impl(self): - raise TypeError( - f"class {self.__class__.__name__} must override method " - f"{ComponentFactoryBase.__name__}.accept()" - ) - if self.type and self.type != "*" and self.type not in JSON_TYPE_NAMES: - raise ValueError( - f"value of {ComponentFactoryBase.__name__}.type must be " - f"one of {', '.join(map(repr, JSON_TYPE_NAMES))}, " - f"but was {self.type!r}" - ) - - # noinspection PyShadowingBuiltins - def accept(self, schema: JsonSchemaDict) -> bool: - other_type = schema.get("type") - other_format = schema.get("format") - type_matches = self.type == other_type or self.type == "*" - format_matches = self.format == other_format or self.format == "*" - return type_matches and format_matches - - @classmethod - def register_in(cls, registry: "ComponentFactoryRegistry"): - """Register this factory in the given registry.""" - registry.register_factory(cls(), type=cls.type, format=cls.format) - - -def _has_own_accept_impl(factory: ComponentFactoryBase) -> bool: - """ - Check if `factory` is an instance of a subclass of `ComponentFactoryBase` - that overrides an instance method named `accept`. - """ - method_name = "accept" - factory_cls = factory.__class__ - if factory_cls is ComponentFactoryBase: - return False - for cls in inspect.getmro(factory_cls): - if cls is ComponentFactoryBase: - break - method = cls.__dict__.get(method_name) - if isinstance(method, FunctionType): - return True - return False diff --git a/s2gos-client/src/s2gos_client/gui/component/impl.py b/s2gos-client/src/s2gos_client/gui/component/impl.py deleted file mode 100644 index bcc9f7c..0000000 --- a/s2gos-client/src/s2gos_client/gui/component/impl.py +++ /dev/null @@ -1,148 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import datetime -import math -from typing import Any, Callable - -import panel as pn - -from .bbox import BboxSelector -from .component import Component, WidgetComponent -from .factory import ComponentFactoryBase -from .json import JsonDateCodec, JsonSchemaDict, JsonValue -from .registry import ComponentFactoryRegistry - - -class BooleanCF(ComponentFactoryBase): - type = "boolean" - - def create_component( - self, value: JsonValue, title: str, schema: JsonSchemaDict - ) -> Component: - value = value if value is not None else False - return WidgetComponent( - pn.widgets.Checkbox(name=title, value=value), - ) - - -class IntegerCF(ComponentFactoryBase): - type = "integer" - - def create_component( - self, value: JsonValue, title: str, schema: JsonSchemaDict - ) -> Component: - value = value if value is not None else 0 - assert isinstance(value, (int, float)) - minimum = schema.get("minimum") - maximum = schema.get("maximum") - if ( - isinstance(minimum, (int, float)) - and isinstance(maximum, (int, float)) - and minimum < maximum - ): - widget = pn.widgets.EditableIntSlider( - name=title, - start=int(minimum), - end=int(maximum), - value=int(value), - step=max(1, pow(10, int(math.log10(maximum - minimum)) - 1) // 10), - ) - else: - widget = pn.widgets.IntInput(name=title, value=int(value)) - return WidgetComponent(widget) - - -class NumberCF(ComponentFactoryBase): - type = "number" - - def create_component( - self, value: JsonValue, title: str, schema: JsonSchemaDict - ) -> Component: - value = value if value is not None else 0 - minimum = schema.get("minimum") - maximum = schema.get("maximum") - if ( - isinstance(minimum, (int, float)) - and isinstance(maximum, (int, float)) - and minimum < maximum - ): - widget = pn.widgets.EditableFloatSlider( - name=title, - start=minimum, - end=maximum, - value=value, - step=pow(10.0, int(math.log10(maximum - minimum)) - 1.0), - ) - else: - widget = pn.widgets.FloatInput(name=title, value=value) - return WidgetComponent(widget) - - -class StringCF(ComponentFactoryBase): - type = "string" - - def create_component( - self, value: JsonValue, title: str, schema: JsonSchemaDict - ) -> Component: - value = value or "" - if "enum" in schema: - widget = pn.widgets.Select(name=title, options=schema["enum"], value=value) - else: - widget = pn.widgets.TextInput(name=title, value=value) - return WidgetComponent(widget) - - -class DateCF(ComponentFactoryBase): - type = "string" - format = "date" - - def create_component( - self, value: JsonValue, title: str, schema: JsonSchemaDict - ) -> Component: - json_codec = JsonDateCodec() - date = json_codec.from_json(value) or datetime.date.today() - return WidgetComponent( - pn.widgets.DatePicker(name=title, value=date), json_codec=json_codec - ) - - -class BboxCF(ComponentFactoryBase): - type = "array" - format = "bbox" - - def create_component( - self, value: JsonValue, title: str, schema: JsonSchemaDict - ) -> Component: - selector = BboxSelector() - # TODO: set value & title - return BboxComponent(selector) - - -class BboxComponent(Component): - def __init__(self, bbox_selector: BboxSelector): - super().__init__(bbox_selector) - - @property - def bbox_selector(self) -> BboxSelector: - # noinspection PyTypeChecker - return self.viewable - - def get_value(self) -> Any: - return self.bbox_selector.value - - def set_value(self, value: Any): - self.bbox_selector.value = value - - def watch_value(self, callback: Callable[[Any], Any]): - self.bbox_selector.param.watch(callback, "value") - - -def register_all(registry: ComponentFactoryRegistry): - BooleanCF.register_in(registry) - IntegerCF.register_in(registry) - NumberCF.register_in(registry) - StringCF.register_in(registry) - DateCF.register_in(registry) - BboxCF.register_in(registry) diff --git a/s2gos-client/src/s2gos_client/gui/component/json.py b/s2gos-client/src/s2gos_client/gui/component/json.py deleted file mode 100644 index c737e05..0000000 --- a/s2gos-client/src/s2gos_client/gui/component/json.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import datetime -from abc import ABC, abstractmethod -from types import NoneType -from typing import Any, Final, Literal, TypeAlias - -JSON_TYPE_NAMES: Final = ("boolean", "integer", "number", "string", "array", "object") - -JsonType: TypeAlias = Literal[ - "boolean", "integer", "number", "string", "array", "object" -] -JsonValue: TypeAlias = ( - bool | int | float | str | list["JsonValue"] | dict[str, "JsonValue"] | None -) -JsonSchemaDict: TypeAlias = dict[str, JsonValue] - - -class JsonCodec(ABC): - """Convert component values to/from JSON values.""" - - @abstractmethod - def to_json(self, value: Any) -> JsonValue: - """Return a JSON value from given Python value.""" - - @abstractmethod - def from_json(self, json_value: JsonValue) -> Any: - """Return a Python value from given JSON value.""" - - -class JsonIdentityCodec(JsonCodec): - def to_json(self, value: Any) -> JsonValue: - assert isinstance(value, (bool, int, float, str, list, dict, NoneType)) - return value - - def from_json(self, json_value: JsonValue) -> Any: - assert isinstance(json_value, (bool, int, float, str, list, dict, NoneType)) - return json_value - - -class JsonDateCodec(JsonCodec): - def to_json(self, value: Any) -> JsonValue: - if not value: - return None - assert isinstance(value, datetime.date) - return datetime.date.isoformat(value) - - def from_json(self, json_value: JsonValue) -> Any: - if not json_value: - return None - assert isinstance(json_value, str) - return datetime.date.fromisoformat(json_value) diff --git a/s2gos-client/src/s2gos_client/gui/component/registry.py b/s2gos-client/src/s2gos_client/gui/component/registry.py deleted file mode 100644 index 1dbd59d..0000000 --- a/s2gos-client/src/s2gos_client/gui/component/registry.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from collections import defaultdict - -from .factory import ComponentFactory -from .json import JsonSchemaDict - -KeyType = tuple[str | None, str | None] - - -class ComponentFactoryRegistry: - """A registry for component factories.""" - - def __init__(self): - self._factories: dict[KeyType, list[ComponentFactory]] = defaultdict(list) - - # noinspection PyShadowingBuiltins - def register_factory( - self, - factory: ComponentFactory, - type: str | None, - format: str | None, - ): - """ - Register a component factory using optional - `type` and `format` as keys. - """ - self._factories[(type, format)].append(factory) - - def find_factory(self, schema: JsonSchemaDict) -> ComponentFactory | None: - schema_type: str | None = schema.get("type") # type: ignore[assignment] - schema_format: str | None = schema.get("format") # type: ignore[assignment] - for t, f in ( - (schema_type, schema_format), - (schema_type, "*"), - ("*", schema_format), - ("*", "*"), - ): - candidate_factories = self._factories.get((t, f)) - if candidate_factories: - # we reverse to have LI-FO behaviour - for factory in reversed(candidate_factories): - if factory.accept(schema): - return factory - return None diff --git a/s2gos-client/src/s2gos_client/gui/job_info_panel.py b/s2gos-client/src/s2gos_client/gui/job_info_panel.py deleted file mode 100644 index 1cc6b1d..0000000 --- a/s2gos-client/src/s2gos_client/gui/job_info_panel.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Any - -import panel -import panel as pn -import param - -from s2gos_client import ClientError -from s2gos_common.models import JobInfo, JobList - -from .jobs_observer import JobsObserver - - -class JobInfoPanel(pn.viewable.Viewer): - job_info = param.ClassSelector(class_=JobInfo, allow_None=True, default=None) - client_error = param.ClassSelector( - class_=ClientError, allow_None=True, default=None - ) - - def __init__(self): - super().__init__() - self._message_pane = panel.pane.Markdown() - self._layout = pn.Column() - self._render_layout() - - def __panel__(self) -> pn.viewable.Viewable: - return self._layout - - def on_job_added(self, job_info: JobInfo): - self.on_job_changed(job_info) - - def on_job_changed(self, job_info: JobInfo): - if self._is_observed_job(job_info): - self.job_info = job_info - - def on_job_removed(self, job_info: JobInfo): - if self._is_observed_job(job_info): - self._message_pane.object = ( - f"Job with ID=`{job_info.jobID}` has been deleted." - ) - self.job_info = None - - def on_job_list_changed(self, job_list: JobList): - # Nothing to do - pass - - def on_job_list_error(self, client_error: ClientError | None): - self.client_error = client_error - - def _is_observed_job(self, job_info): - return self.job_info is not None and self.job_info.jobID == job_info.jobID - - @param.depends("job_info", "client_error", watch=True) - def _render_layout(self): - if self.client_error is not None: - self._layout[:] = [pn.pane.Markdown(f"⚠️ Error: {self.client_error}")] - return - - job_info: JobInfo = self.job_info - if job_info is None: - self._message_pane.object = "ℹ️ No job selected." - self._layout.objects[:] = [self._message_pane] - return - - column1 = pn.Column( - pn.widgets.StaticText(name="Process ID", value=job_info.processID), - pn.widgets.StaticText(name="Job ID", value=job_info.jobID), - pn.widgets.StaticText(name="Status", value=job_info.status), - pn.widgets.StaticText( - name="Progress", value=_to_value(job_info.progress, "%") - ), - ) - column2 = pn.Column( - pn.widgets.StaticText(name="Created", value=_to_value(job_info.created)), - pn.widgets.StaticText(name="Started", value=_to_value(job_info.started)), - pn.widgets.StaticText(name="Updated", value=_to_value(job_info.updated)), - pn.widgets.StaticText(name="Finished", value=_to_value(job_info.finished)), - ) - self._message_pane.object = job_info.message or "" - self._layout[:] = [self._message_pane, pn.Row(column1, column2)] - # pn.state.notifications.success(f"Change {job_info.updated}", duration=1000) - - -# Register JobInfoPanel as a virtual subclass of JobsObserver -JobsObserver.register(JobInfoPanel) - - -def _to_value(value: Any, units: str = ""): - return f"{value}{units}" if value is not None else "-" diff --git a/s2gos-client/src/s2gos_client/gui/jobs_observer.py b/s2gos-client/src/s2gos_client/gui/jobs_observer.py deleted file mode 100644 index 9ac7704..0000000 --- a/s2gos-client/src/s2gos_client/gui/jobs_observer.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from abc import ABC, abstractmethod - -from s2gos_client import ClientError -from s2gos_common.models import JobInfo, JobList - - -class JobsObserver(ABC): - """Observes job and job list changes.""" - - @abstractmethod - def on_job_added(self, job_info: JobInfo): - """Called after a job has been added.""" - - @abstractmethod - def on_job_changed(self, job_info: JobInfo): - """Called after a job has been changed.""" - - @abstractmethod - def on_job_removed(self, job_info: JobInfo): - """Called after a job has been removed.""" - - @abstractmethod - def on_job_list_changed(self, job_list: JobList): - """Called after the current list of jobs changed.""" - - @abstractmethod - def on_job_list_error(self, error: ClientError | None): - """Called if an error occurred while getting current list of jobs.""" diff --git a/s2gos-client/src/s2gos_client/gui/jobs_panel.py b/s2gos-client/src/s2gos_client/gui/jobs_panel.py deleted file mode 100644 index 4677dfd..0000000 --- a/s2gos-client/src/s2gos_client/gui/jobs_panel.py +++ /dev/null @@ -1,288 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Any, Callable, Optional, TypeAlias - -import pandas as pd -import panel as pn -from pydantic import BaseModel - -from s2gos_client.api.exceptions import ClientError -from s2gos_common.models import JobInfo, JobList, JobResults, JobStatus - -from .jobs_observer import JobsObserver -from .util import JsonDict - -JobAction: TypeAlias = Callable[[str], Any] - - -class JobsPanel(pn.viewable.Viewer): - def __init__( - self, - on_delete_job: Optional[JobAction] = None, - on_cancel_job: Optional[JobAction] = None, - on_restart_job: Optional[JobAction] = None, - on_get_job_results: Optional[JobAction] = None, - ): - super().__init__() - self._jobs: list[JobInfo] = [] - self._client_error: ClientError | None = None - - self._on_delete_job = on_delete_job - self._on_cancel_job = on_cancel_job - self._on_restart_job = on_restart_job - self._on_get_job_results = on_get_job_results - self._tabulator = self._new_tabulator() - self._tabulator.param.watch(self._update_buttons, "selection") - # A placeholder for clicked action - self._cancel_button = pn.widgets.Button( - name="Cancel", - # tooltip="Cancels the selected job(s)", - button_type="primary", - on_click=self._on_cancel_jobs_clicked, - disabled=True, - ) - self._delete_button = pn.widgets.Button( - name="Delete", - # tooltip="Deletes the selected job(s)", - button_type="danger", - on_click=self._on_delete_jobs_clicked, - disabled=True, - ) - self._restart_button = pn.widgets.Button( - name="Restart", - # tooltip="Restarts the selected job(s)", - button_type="primary", - on_click=self._on_restart_jobs_clicked, - disabled=True, - ) - self._get_results_button = pn.widgets.Button( - name="Get Results", - # tooltip="Gets the results from the selected job(s)", - button_type="primary", - on_click=self._on_get_job_result_clicked, - disabled=True, - ) - self._action_row = pn.Row( - self._cancel_button, - self._delete_button, - self._restart_button, - self._get_results_button, - ) - self._message_md = pn.pane.Markdown("") - self._view = pn.Column( - self._tabulator, - self._action_row, - self._message_md, - ) - - def __panel__(self) -> pn.viewable.Viewable: - return self._view - - def on_job_added(self, _job_info: JobInfo): - pass - - def on_job_removed(self, _job_info: JobInfo): - pass - - def on_job_changed(self, _job_info: JobInfo): - pass - - def on_job_list_changed(self, job_list: JobList): - self._jobs = list(job_list.jobs) - dataframe = _jobs_to_dataframe(job_list.jobs) - self._tabulator.value = dataframe - self._update_buttons() - - def on_job_list_error(self, error: ClientError | None): - # TODO: render error - self._client_error = error - self._update_buttons() - - def _update_buttons(self, _event: Any = None): - selected_jobs = self.get_selected_jobs() - - self._cancel_button.disabled = ( - self._on_cancel_job is None - or not _job_requirements_fulfilled( - selected_jobs, {JobStatus.accepted, JobStatus.running} - ) - ) - self._delete_button.disabled = ( - self._on_delete_job is None - or not _job_requirements_fulfilled( - selected_jobs, - {JobStatus.successful, JobStatus.dismissed, JobStatus.failed}, - ) - ) - self._restart_button.disabled = ( - self._on_restart_job is None - or not _job_requirements_fulfilled( - selected_jobs, - {JobStatus.successful, JobStatus.dismissed, JobStatus.failed}, - ) - ) - self._get_results_button.disabled = ( - self._on_get_job_results is None - or len(selected_jobs) != 1 - or not _job_requirements_fulfilled( - selected_jobs, {JobStatus.successful, JobStatus.failed} - ) - ) - - def get_selected_jobs(self) -> list[JobInfo]: - """Get selected jobs from jobs table.""" - selection = self._tabulator.selection - if not selection: - return [] - selected_ids = {self._jobs[row].jobID for row in selection} - return [job for job in self._jobs if job.jobID in selected_ids] - - def _on_cancel_jobs_clicked(self, _event: Any): - self._run_action_on_selected_jobs( - self._on_cancel_job, - "✅ Cancelled {job}", - "⚠️ Failed cancelling {job}: {message}", - ) - - def _on_delete_jobs_clicked(self, _event: Any): - self._run_action_on_selected_jobs( - self._on_delete_job, - "✅ Deleted {job}", - "⚠️ Failed deleting {job}: {message}", - ) - - def _on_restart_jobs_clicked(self, _event: Any): - self._run_action_on_selected_jobs( - self._on_restart_job, - "✅ Restarted {job}", - "⚠️ Failed restarting {job}: {message}", - ) - - def _on_get_job_result_clicked(self, _event: Any): - def handle_results(_job_id: str, results: JobResults | dict): - # noinspection PyProtectedMember - from IPython import get_ipython - - results_value: Any = results - if isinstance(results_value, JobResults): - results_value = results_value.root - if isinstance(results_value, dict): - results_value = JsonDict( - "Results", - { - k: (v.model_dump() if isinstance(v, BaseModel) else v) - for k, v in results_value.items() - }, - ) - var_name = "_results" - get_ipython().user_ns[var_name] = results_value - return "✅ Stored results of {job} " + f"in variable **`{var_name}`**" - - self._run_action_on_selected_jobs( - self._on_get_job_results, - handle_results, - "⚠️ Failed to get results for {job}: {message}", - ) - - def _run_action_on_selected_jobs( - self, - action: JobAction | None, - success_format: str | Callable[[str, Any], str] | None, - error_format: str, - ): - if action is None: - return - messages = [] - for job in self.get_selected_jobs(): - job_id = job.jobID - job_text = f"job `{job_id}`" - try: - result = action(job_id) - if isinstance(success_format, str): - messages.append(success_format.format(job=job_text)) - elif callable(success_format): - messages.append(success_format(job_id, result).format(job=job_text)) - except ClientError as e: - # TODO: also show e.api_error.traceback, when user expands the message - messages.append( - error_format.format( - job=job_text, - message=(f"{e}: {e.api_error.detail}"), - ) - ) - self._message_md.object = " \n".join(messages) - - @classmethod - def _new_tabulator(cls) -> pn.widgets.Tabulator: - dataframe = _jobs_to_dataframe([]) - - tabulator = pn.widgets.Tabulator( - dataframe, - theme="default", - width=600, - height=300, - layout="fit_data", - show_index=False, - editors={}, # No editing - # selectable=False, - disabled=True, - configuration={ - "columns": [ - {"title": "Process ID", "field": "process_id"}, - {"title": "Job ID", "field": "job_id"}, - {"title": "Status", "field": "status"}, - { - "title": "Progress", - "field": "progress", - "formatter": "progress", - "formatterParams": { - "min": 0, - "max": 100, - "color": [ - "#f00", - "#ffa500", - "#ff0", - "#0f0", - ], # red → orange → yellow → green - }, - }, - {"title": "Message", "field": "message"}, - { - "title": " ", - "field": "action", - "hozAlign": "center", - "formatter": "plaintext", - "cellClick": True, # Needed to enable cell-level events - "cssClass": "action-cell", # We'll style this column - }, - ] - }, - ) - - return tabulator - - -# Register JobsPanel as a virtual subclass of JobsObserver -JobsObserver.register(JobsPanel) - - -def _jobs_to_dataframe(jobs: list[JobInfo]): - return pd.DataFrame([_job_to_dataframe_row(job) for job in jobs]) - - -def _job_to_dataframe_row(job: JobInfo): - return { - "process_id": job.processID, - "job_id": job.jobID, - "status": job.status.value, - "progress": job.progress or 0, - "message": job.message or "-", - } - - -def _job_requirements_fulfilled( - jobs: list[JobInfo], requirements: set[JobStatus] -) -> bool: - return bool(jobs) and all(j.status in requirements for j in jobs) diff --git a/s2gos-client/src/s2gos_client/gui/main_panel.py b/s2gos-client/src/s2gos_client/gui/main_panel.py deleted file mode 100644 index d37880e..0000000 --- a/s2gos-client/src/s2gos_client/gui/main_panel.py +++ /dev/null @@ -1,233 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Any, Callable, TypeAlias - -import panel as pn -import param - -from s2gos_client.api.exceptions import ClientError -from s2gos_common.models import ( - JobInfo, - JobList, - ProcessDescription, - ProcessList, - ProcessRequest, -) -from s2gos_common.process import ExecutionRequest - -from .component.container import ComponentContainer -from .job_info_panel import JobInfoPanel -from .jobs_observer import JobsObserver - -ExecuteProcessAction: TypeAlias = Callable[[str, ProcessRequest], JobInfo] -GetProcessAction: TypeAlias = Callable[[str], ProcessDescription] - - -class MainPanel(pn.viewable.Viewer): - # can be normal list - _processes = param.List(default=[], doc="List of process summaries") - # can be normal dict - _processes_dict = param.Dict(default={}, doc="Dictionary of cached processes") - - def __init__( - self, - process_list: ProcessList, - process_list_error: ClientError | None, - on_get_process: GetProcessAction, - on_execute_process: ExecuteProcessAction, - ): - super().__init__() - self._processes = process_list.processes - self._process_list_error = process_list_error - - self._on_execute_process = on_execute_process - self._on_get_process = on_get_process - - process_select_options = [p.id for p in process_list.processes] - if process_select_options: - process_id = process_select_options[0] - else: - process_id = None - - self._process_select = pn.widgets.Select( - name="Process", options=process_select_options, value=process_id - ) - self._process_select.param.watch( - lambda e: self._on_process_id_changed(e.new), "value" - ) - - self._process_doc_markdown = pn.pane.Markdown("") - process_panel = pn.Column( - # pn.pane.Markdown("# Process"), - self._process_select, - self._process_doc_markdown, - ) - - self._execute_button = pn.widgets.Button( - name="Execute", - # tooltip="Executes the selected process with the current request", - button_type="primary", - on_click=self._on_execute_button_clicked, - disabled=True, - ) - self._open_button = pn.widgets.Button( - name="Open", - on_click=self._on_open_request_clicked, - disabled=True, - ) - self._save_button = pn.widgets.Button( - name="Save", - on_click=self._on_save_request_clicked, - disabled=True, - ) - self._save_as_button = pn.widgets.Button( - name="Save As...", - on_click=self._on_save_as_request_clicked, - disabled=True, - ) - self._request_button = pn.widgets.Button( - name="Get Request", - on_click=self._on_get_process_request, - disabled=True, - ) - - action_panel = pn.Row( - self._execute_button, - self._open_button, - self._save_button, - self._save_as_button, - self._request_button, - ) - - self._inputs_panel = pn.Column() - self._outputs_panel = pn.Column() - - self._last_job_info: JobInfo | None = None - self._job_info_panel = JobInfoPanel() - - self._view = pn.Column( - process_panel, - self._inputs_panel, - self._outputs_panel, - action_panel, - self._job_info_panel, - ) - - self._component_container: ComponentContainer | None = None - - self._on_process_id_changed(process_id) - - def __panel__(self) -> pn.viewable.Viewable: - return self._view - - def on_job_added(self, job_info: JobInfo): - self._job_info_panel.on_job_added(job_info) - - def on_job_changed(self, job_info: JobInfo): - self._job_info_panel.on_job_changed(job_info) - - def on_job_removed(self, job_info: JobInfo): - self._job_info_panel.on_job_removed(job_info) - - def on_job_list_changed(self, job_list: JobList): - pass - - def on_job_list_error(self, job_list: JobList): - # TODO: render error - pass - - def _on_process_id_changed(self, process_id: str | None = None): - process_description: ProcessDescription | None = None - process_markdown: str | None = None - if not process_id: - process_markdown = "_No process selected._" - else: - if process_id in self._processes_dict: - process_description = self._processes_dict[process_id] - else: - try: - process_description = self._on_get_process(process_id) - self._processes_dict[process_id] = process_description - except ClientError as e: - # TODO: also show e.api_error.traceback, when user expands the message - process_description = None - process_markdown = f"**Error**: {e}: {e.api_error.detail}" - if process_description: - process_markdown = ( - f"**{process_description.title}**\n\n" - f"{process_description.description}" - ) - - self._process_doc_markdown.object = process_markdown - if not process_description: - self._execute_button.disabled = True - self._request_button.disabled = True - self._component_container = None - self._inputs_panel[:] = [] - self._outputs_panel[:] = [] - else: - self._execute_button.disabled = False - self._request_button.disabled = False - self._component_container = ComponentContainer.from_input_descriptions( - process_description.inputs or {}, {} - ) - self._inputs_panel[:] = self._component_container.get_viewables() - self._outputs_panel[:] = [] - - def _on_execute_button_clicked(self, _event: Any = None): - execution_request = self._new_execution_request() - try: - self._execute_button.disabled = True - job_info = self._on_execute_process( - execution_request.process_id, execution_request.to_process_request() - ) - self._job_info_panel.job_info = job_info - except ClientError as e: - self._job_info_panel.client_error = e - finally: - self._execute_button.disabled = False - - def _on_open_request_clicked(self, _event: Any = None): - # TODO implement open request - pass - - def _on_save_request_clicked(self, _event: Any = None): - # TODO implement save request - pass - - def _on_save_as_request_clicked(self, _event: Any = None): - # TODO implement save request as - pass - - def _on_get_process_request(self, _event: Any = None): - # noinspection PyProtectedMember - from IPython import get_ipython - - var_name = "_request" - get_ipython().user_ns[var_name] = self._new_execution_request() - - def _update_buttons(self): - # TODO implement action enablement - pass - - def _new_execution_request(self) -> ExecutionRequest: - process_id = self._process_select.value - assert process_id is not None - - process_description = self._processes_dict.get(process_id) - assert process_description is not None - - component_container = self._component_container - assert component_container is not None - - return ExecutionRequest( - process_id=process_id, - dotpath=True, - inputs=component_container.get_json_values(), - ) - - -# Register MainPanel as a virtual subclass of JobsObserver -JobsObserver.register(MainPanel) diff --git a/s2gos-client/src/s2gos_client/gui/util.py b/s2gos-client/src/s2gos_client/gui/util.py deleted file mode 100644 index d878bf0..0000000 --- a/s2gos-client/src/s2gos_client/gui/util.py +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - - -class JsonDict(dict): - def __init__(self, name: str, *args, **kwargs): - super().__init__(*args, **kwargs) - self._name = name - - def _repr_json_(self): - return self, {"root": f"{self._name}:"} diff --git a/s2gos-client/src/tests/api/__init__.py b/s2gos-client/src/tests/api/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-client/src/tests/api/test_async_client.py b/s2gos-client/src/tests/api/test_async_client.py deleted file mode 100644 index de68d42..0000000 --- a/s2gos-client/src/tests/api/test_async_client.py +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import IsolatedAsyncioTestCase - -from tests.helpers import MockTransport - -from s2gos_client import ClientConfig -from s2gos_client.api.async_client import AsyncClient -from s2gos_common.models import ( - Capabilities, - ConformanceDeclaration, - JobInfo, - JobList, - JobResults, - ProcessDescription, - ProcessList, - ProcessRequest, -) -from s2gos_common.process import ExecutionRequest - - -class AsyncClientTest(IsolatedAsyncioTestCase): - # noinspection PyPep8Naming - async def asyncSetUp(self): - self.transport = MockTransport() - self.client = AsyncClient(_transport=self.transport) - - async def test_config(self): - self.assertIsInstance(self.client.config, ClientConfig) - - async def test_repr_json(self): - result = self.client._repr_json_() - self.assertIsInstance(result, tuple) - self.assertEqual(2, len(result)) - data, metadata = result - self.assertIsInstance(data, dict) - self.assertIsInstance(metadata, dict) - self.assertEqual({"root": "Client configuration:"}, metadata) - - async def test_create_execution_request(self): - request = await self.client.create_execution_request( - process_id="ID-1", - ) - self.assertEqual( - ExecutionRequest(process_id="ID-1", inputs={}), - request, - ) - - async def test_create_execution_request_dotpath(self): - request = await self.client.create_execution_request( - process_id="ID-1", dotpath=True - ) - self.assertEqual( - ExecutionRequest(process_id="ID-1", inputs={}, dotpath=True), - request, - ) - - async def test_get_capabilities(self): - result = await self.client.get_capabilities() - self.assertIsInstance(result, Capabilities) - - async def test_get_conformance(self): - result = await self.client.get_conformance() - self.assertIsInstance(result, ConformanceDeclaration) - - async def test_get_processes(self): - result = await self.client.get_processes() - self.assertIsInstance(result, ProcessList) - - async def test_get_process(self): - result = await self.client.get_process(process_id="gobabeb_1") - self.assertIsInstance(result, ProcessDescription) - - async def test_execute_process(self): - result = await self.client.execute_process( - process_id="gobabeb_1", - request=ProcessRequest( - inputs={"bbox": [10, 20, 30, 40]}, - outputs={}, - ), - ) - self.assertIsInstance(result, JobInfo) - - async def test_get_jobs(self): - result = await self.client.get_jobs() - self.assertIsInstance(result, JobList) - - async def test_dismiss_job(self): - result = await self.client.dismiss_job("job_12") - self.assertIsInstance(result, JobInfo) - - async def test_get_job(self): - result = await self.client.get_job("job_12") - self.assertIsInstance(result, JobInfo) - - async def test_get_job_results(self): - result = await self.client.get_job_results("job_12") - self.assertIsInstance(result, JobResults) - - async def test_close(self): - self.assertFalse(self.transport.closed) - await self.client.close() - self.assertTrue(self.transport.closed) diff --git a/s2gos-client/src/tests/api/test_client.py b/s2gos-client/src/tests/api/test_client.py deleted file mode 100644 index b2e8ea6..0000000 --- a/s2gos-client/src/tests/api/test_client.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -from tests.helpers import MockTransport - -from s2gos_client import ClientConfig -from s2gos_client.api.client import Client -from s2gos_common.models import ( - Capabilities, - ConformanceDeclaration, - JobInfo, - JobList, - JobResults, - ProcessDescription, - ProcessList, - ProcessRequest, -) -from s2gos_common.process import ExecutionRequest - - -class ClientTest(TestCase): - def setUp(self): - self.transport = MockTransport() - self.client = Client(config=ClientConfig(), _transport=self.transport) - - def test_config(self): - self.assertIsInstance(self.client.config, ClientConfig) - - def test_repr_json(self): - result = self.client._repr_json_() - self.assertIsInstance(result, tuple) - self.assertEqual(2, len(result)) - data, metadata = result - self.assertIsInstance(data, dict) - self.assertIsInstance(metadata, dict) - self.assertEqual({"root": "Client configuration:"}, metadata) - - def test_create_execution_request(self): - self.assertEqual( - ExecutionRequest(process_id="ID-1", inputs={}), - self.client.create_execution_request( - process_id="ID-1", - ), - ) - - def test_create_execution_request_dotpath(self): - self.assertEqual( - ExecutionRequest(process_id="ID-1", inputs={}, dotpath=True), - self.client.create_execution_request(process_id="ID-1", dotpath=True), - ) - - def test_get_capabilities(self): - result = self.client.get_capabilities() - self.assertIsInstance(result, Capabilities) - - def test_get_conformance(self): - result = self.client.get_conformance() - self.assertIsInstance(result, ConformanceDeclaration) - - def test_get_processes(self): - result = self.client.get_processes() - self.assertIsInstance(result, ProcessList) - - def test_get_process(self): - result = self.client.get_process(process_id="gobabeb_1") - self.assertIsInstance(result, ProcessDescription) - - def test_execute_process(self): - result = self.client.execute_process( - process_id="gobabeb_1", - request=ProcessRequest( - inputs={"bbox": [10, 20, 30, 40]}, - outputs={}, - ), - ) - self.assertIsInstance(result, JobInfo) - - def test_get_jobs(self): - result = self.client.get_jobs() - self.assertIsInstance(result, JobList) - - def test_dismiss_job(self): - result = self.client.dismiss_job("job_12") - self.assertIsInstance(result, JobInfo) - - def test_get_job(self): - result = self.client.get_job("job_12") - self.assertIsInstance(result, JobInfo) - - def test_get_job_results(self): - result = self.client.get_job_results("job_12") - self.assertIsInstance(result, JobResults) - - def test_close(self): - self.assertFalse(self.transport.closed) - self.client.close() - self.assertTrue(self.transport.closed) diff --git a/s2gos-client/src/tests/api/test_config.py b/s2gos-client/src/tests/api/test_config.py deleted file mode 100644 index b624eeb..0000000 --- a/s2gos-client/src/tests/api/test_config.py +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import os -import tempfile -from pathlib import Path -from unittest import TestCase - -from s2gos_client.api.config import ClientConfig -from s2gos_client.api.defaults import DEFAULT_CONFIG_PATH - - -class ClientConfigTest(TestCase): - def setUp(self): - self.saved_environ = { - k: v for k, v in os.environ.items() if k.startswith("S2GOS_") - } - for k in self.saved_environ.keys(): - del os.environ[k] - - def tearDown(self): - self.saved_environ = { - k: v for k, v in os.environ.items() if k.startswith("S2GOS_") - } - for k, v in self.saved_environ.items(): - os.environ[k] = v - - def test_ctor(self): - config = ClientConfig() - self.assertEqual(None, config.user_name) - self.assertEqual(None, config.access_token) - self.assertEqual(None, config.server_url) - - def test_create_empty(self): - with tempfile.TemporaryDirectory() as tmp_dir_name: - config_path = Path(tmp_dir_name) / "config" - config = ClientConfig.create(config_path=config_path) - self.assertIsInstance(config, ClientConfig) - self.assertEqual("http://127.0.0.1:8008", config.server_url) - self.assertEqual(None, config.user_name) - self.assertEqual(None, config.access_token) - - def test_create_from_env(self): - os.environ.update( - dict( - S2GOS_SERVER_URL="https://s2gos.test.api", - S2GOS_USER_NAME="pippo", - S2GOS_ACCESS_TOKEN="0f8915a4", - ) - ) - with tempfile.TemporaryDirectory() as tmp_dir_name: - config_path = Path(tmp_dir_name) / "config" - config = ClientConfig.create(config_path=config_path) - self.assertIsInstance(config, ClientConfig) - self.assertEqual("https://s2gos.test.api", config.server_url) - self.assertEqual("pippo", config.user_name) - self.assertEqual("0f8915a4", config.access_token) - - def test_create_from_file(self): - config = ClientConfig( - server_url="https://s2gos.test2.api", user_name="bibo", access_token="981b" - ) - with tempfile.TemporaryDirectory() as tmp_dir_name: - config_path = Path(tmp_dir_name) / "config" - config.write(config_path=config_path) - config = ClientConfig.create(config_path=config_path) - self.assertEqual("https://s2gos.test2.api", config.server_url) - self.assertEqual("bibo", config.user_name) - self.assertEqual("981b", config.access_token) - - def test_create_from_file_and_env(self): - os.environ.update( - dict( - S2GOS_SERVER_URL="https://s2gos.test.api", - S2GOS_USER_NAME="pippo", - S2GOS_ACCESS_TOKEN="0f8915a4", - ) - ) - config = ClientConfig(server_url="https://s2gos.test2.api", user_name="bibi") - with tempfile.TemporaryDirectory() as tmp_dir_name: - config_path = Path(tmp_dir_name) / "config" - config.write(config_path=config_path) - config = ClientConfig.create(config_path=config_path) - self.assertEqual("https://s2gos.test.api", config.server_url) - self.assertEqual("pippo", config.user_name) - self.assertEqual("0f8915a4", config.access_token) - - def test_normalize_config_path(self): - path = Path("i/am/a/path") - self.assertIs(path, ClientConfig.normalize_config_path(path)) - self.assertEqual(path, ClientConfig.normalize_config_path("i/am/a/path")) - self.assertEqual(DEFAULT_CONFIG_PATH, ClientConfig.normalize_config_path("")) diff --git a/s2gos-client/src/tests/api/test_ishell.py b/s2gos-client/src/tests/api/test_ishell.py deleted file mode 100644 index 7549e79..0000000 --- a/s2gos-client/src/tests/api/test_ishell.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -from IPython.core.interactiveshell import InteractiveShell - -from s2gos_client import ClientError -from s2gos_client.api.ishell import exception_handler, has_ishell -from s2gos_common.models import ApiError - - -class IShellTest(TestCase): - def test_has_ishell_ok(self): - self.assertTrue(has_ishell) - - def test_exception_handler_ok(self): - self.assertIsNotNone(exception_handler) - self.assertTrue(callable(exception_handler)) - - def test_exception_handler_with_client_exception(self): - exc = ClientError( - "What the heck", ApiError(type="error", title="Don't worry, be happy") - ) - result = exception_handler( - InteractiveShell.instance(), - type(exc), - exc, - None, - ) - self.assertEqual((None, None, None), result) - - def test_exception_handler_with_value_error(self): - exc = ValueError("Too large") - result = exception_handler( - InteractiveShell.instance(), - type(exc), - exc, - None, - ) - self.assertEqual(None, result) diff --git a/s2gos-client/src/tests/api/transport/__init__.py b/s2gos-client/src/tests/api/transport/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-client/src/tests/api/transport/test_args.py b/s2gos-client/src/tests/api/transport/test_args.py deleted file mode 100644 index 9f44959..0000000 --- a/s2gos-client/src/tests/api/transport/test_args.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -from s2gos_client.api.exceptions import ClientError -from s2gos_client.api.transport import TransportArgs -from s2gos_common.models import ApiError - - -class TransportArgsTest(TestCase): - def test_get_error_for_json_ok(self): - args = TransportArgs("/jobs", method="get") - client_error = args.get_exception_for_status( - 401, - "Not implemented", - {"type": "ValueError", "title": "No jobs", "status": 401}, - ) - self.assertIsInstance(client_error, ClientError) - self.assertEqual("Not implemented (status 401)", f"{client_error}") - self.assertIsInstance(client_error.api_error, ApiError) - self.assertEqual( - ApiError(type="ValueError", title="No jobs", status=401), - client_error.api_error, - ) - - def test_get_error_for_json_fail_1(self): - args = TransportArgs("/jobs", method="get") - client_error = args.get_exception_for_status( - 501, "Not implemented", {"message": "Wrong error"} - ) - self.assertIsInstance(client_error, ClientError) - self.assertEqual("Not implemented (status 501)", f"{client_error}") - self.assertIsInstance(client_error.api_error, ApiError) - self.assertEqual("ValidationError", client_error.api_error.type) - - def test_get_error_for_json_fail_2(self): - args = TransportArgs("/jobs", method="get") - client_error = args.get_exception_for_status(501, "Not implemented", 13) - self.assertIsInstance(client_error, ClientError) - self.assertEqual("Not implemented (status 501)", f"{client_error}") - self.assertIsInstance(client_error.api_error, ApiError) - self.assertEqual("ValidationError", client_error.api_error.type) diff --git a/s2gos-client/src/tests/api/transport/test_httpx.py b/s2gos-client/src/tests/api/transport/test_httpx.py deleted file mode 100644 index 9c938dd..0000000 --- a/s2gos-client/src/tests/api/transport/test_httpx.py +++ /dev/null @@ -1,213 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Any, Callable -from unittest import IsolatedAsyncioTestCase, TestCase -from unittest.mock import AsyncMock, MagicMock - -import httpx -import pytest - -from s2gos_client.api.exceptions import ClientError -from s2gos_client.api.transport import TransportArgs, TransportError -from s2gos_client.api.transport.httpx import HttpxTransport -from s2gos_common.models import ApiError, ConformanceDeclaration - - -def make_mocked_transport( - status_code: int, - json_return_value: Any = None, - json_side_effect: Callable | None = None, - raise_for_status_side_effect: Callable | None = None, - reason: str | None = None, -): - response = MagicMock() - response.status_code = status_code - response.reason = reason - response.json.return_value = json_return_value - response.json.side_effect = json_side_effect - response.raise_for_status.side_effect = raise_for_status_side_effect - - sync_httpx = MagicMock() - sync_httpx.request.return_value = response - - async_httpx = MagicMock() - async_httpx.request = AsyncMock(return_value=response) - - transport = HttpxTransport(server_url="https://api.example.com") - transport.sync_httpx = sync_httpx - transport.async_httpx = async_httpx - return transport - - -class HttpxSyncTransportTest(TestCase): - def test_sync_call_initializes_correctly(self): - transport = HttpxTransport(server_url="https://api.example.com") - self.assertIsNone(transport.sync_httpx) - with pytest.raises(TransportError): - transport.call(TransportArgs("/")) - self.assertIsInstance(transport.sync_httpx, httpx.Client) - - def test_call_success_200(self): - transport = make_mocked_transport( - 200, - {"conformsTo": ["Hello", "World"]}, - ) - result = transport.call( - TransportArgs( - path="/conformance", - method="get", - return_types={"200": ConformanceDeclaration}, - error_types={"401": ApiError}, - ) - ) - # noinspection PyUnresolvedReferences - transport.sync_httpx.request.assert_called_once_with( - "GET", - "https://api.example.com/conformance", - params={}, - json=None, - ) - self.assertIsInstance(result, ConformanceDeclaration) - - def test_call_success_201(self): - transport = make_mocked_transport( - 201, - {"conformsTo": ["Hello", "World"]}, - ) - result = transport.call( - TransportArgs( - path="/conformance", - method="get", - return_types={"201": ConformanceDeclaration}, - error_types={"401": ApiError}, - ) - ) - # noinspection PyUnresolvedReferences - transport.sync_httpx.request.assert_called_once_with( - "GET", - "https://api.example.com/conformance", - params={}, - json=None, - ) - self.assertIsInstance(result, ConformanceDeclaration) - - def test_call_success_no_return_type(self): - transport = make_mocked_transport( - 200, - {"conformsTo": ["Hello", "World"]}, - ) - result = transport.call( - TransportArgs( - path="/conformance", method="get", error_types={"401": ApiError} - ) - ) - # noinspection PyUnresolvedReferences - transport.sync_httpx.request.assert_called_once_with( - "GET", - "https://api.example.com/conformance", - params={}, - json=None, - ) - self.assertEqual({"conformsTo": ["Hello", "World"]}, result) - - # noinspection PyMethodMayBeStatic - def test_call_raise_for_status_fail(self): - def panic(): - raise httpx.HTTPError("Panic!") - - transport = make_mocked_transport( - 401, - {"type": "error", "detail": "So sorry"}, - raise_for_status_side_effect=panic, - reason="Conformance not found", - ) - args = TransportArgs( - path="/conformance", - method="get", - return_types={"200": ConformanceDeclaration}, - error_types={"401": ApiError}, - ) - with pytest.raises(ClientError, match="Panic!") as e: - transport.call(args) - ce: ClientError = e.value - self.assertEqual("Panic! (status 401)", str(ce)) - self.assertEqual(ApiError(type="error", detail="So sorry"), ce.api_error) - - def test_call_json_fail(self): - def panic(): - raise ValueError("This is no JSON") - - transport = make_mocked_transport( - 500, - json_side_effect=panic, - ) - args = TransportArgs( - path="/conformance", - method="get", - return_types={"200": ConformanceDeclaration}, - error_types={"401": ApiError}, - ) - with pytest.raises(ClientError, match="This is no JSON") as e: - transport.call(args) - ce: ClientError = e.value - self.assertEqual("This is no JSON", str(ce)) - self.assertEqual( - ApiError( - type="ValueError", - title="Expected JSON response from API", - detail="This is no JSON", - ), - ce.api_error, - ) - - def test_close(self): - sync_httpx = MagicMock() - - transport = HttpxTransport(server_url="https://api.example.com") - transport.sync_httpx = sync_httpx - - transport.close() - self.assertIsNone(transport.sync_httpx) - - -class HttpxAsyncTransportTest(IsolatedAsyncioTestCase): - async def test_async_call_initializes_correctly(self): - transport = HttpxTransport(server_url="https://api.example.com") - self.assertIsNone(transport.async_httpx) - with pytest.raises(TransportError): - await transport.async_call(TransportArgs("/")) - self.assertIsInstance(transport.async_httpx, httpx.AsyncClient) - - async def test_async_call_success(self): - transport = make_mocked_transport( - 200, - {"conformsTo": ["Hello", "World"]}, - ) - result = await transport.async_call( - TransportArgs( - path="/conformance", - method="get", - return_types={"200": ConformanceDeclaration}, - error_types={"401": ApiError}, - ) - ) - # noinspection PyUnresolvedReferences - transport.async_httpx.request.assert_called_once_with( - "GET", - "https://api.example.com/conformance", - params={}, - json=None, - ) - self.assertIsInstance(result, ConformanceDeclaration) - - async def test_async_close(self): - async_httpx = MagicMock() - - transport = HttpxTransport(server_url="https://api.example.com") - transport.async_httpx = async_httpx - transport.async_httpx.aclose = AsyncMock(return_value=None) - - await transport.async_close() - self.assertIsNone(transport.async_httpx) diff --git a/s2gos-client/src/tests/cli/__init__.py b/s2gos-client/src/tests/cli/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-client/src/tests/cli/test_cli.py b/s2gos-client/src/tests/cli/test_cli.py deleted file mode 100644 index 51f6abf..0000000 --- a/s2gos-client/src/tests/cli/test_cli.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from pathlib import Path -from unittest import TestCase - -import typer.testing -from tests.helpers import MockTransport - -from s2gos_client import Client, ClientConfig, __version__ -from s2gos_client.cli.cli import cli - - -def invoke_cli(*args: str) -> typer.testing.Result: - def get_mock_client(_config_path: str | None): - return Client(config=ClientConfig(), _transport=MockTransport()) - - runner = typer.testing.CliRunner() - return runner.invoke(cli, args, obj={"get_client": get_mock_client}) - - -class CliTest(TestCase): - def test_help(self): - result = invoke_cli("--help") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertIn("tool for the S2GOS service.", result.output) - - def test_version(self): - result = invoke_cli("--version") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual(__version__ + "\n", result.output) - - def test_configure(self): - config_path = Path("config.cfg") - result = invoke_cli( - "configure", - "-c", - str(config_path), - "-u", - "bibo", - "-t", - "1234", - "-s", - "http://localhorst:2357", - ) - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertTrue(config_path.exists()) - config_path.unlink() - - def test_get_processes(self): - result = invoke_cli("list-processes") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual("links: []\nprocesses: []\n\n", result.output) - - def test_get_process(self): - result = invoke_cli("get-process", "sleep_a_while") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual("id: ID-1\nversion: ''\n\n", result.output) - - def test_create_request(self): - result = invoke_cli("create-request", "sleep_a_while") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual( - "inputs: {}\nprocess_id: ID-1\n\n", - result.output, - ) - - def test_validate_request(self): - result = invoke_cli( - "validate-request", "sleep_a_while", "-i", "duration=120", "-i", "fail=true" - ) - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual( - "inputs:\n duration: 120\n fail: true\nprocess_id: sleep_a_while\n\n", - result.output, - ) - - def test_execute_process(self): - result = invoke_cli( - "execute-process", "sleep_a_while", "-i", "duration=120", "-i", "fail=true" - ) - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual( - "jobID: ''\nstatus: accepted\ntype: process\n\n", result.output - ) - - def test_list_jobs(self): - result = invoke_cli("list-jobs") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual("jobs: []\nlinks: []\n\n", result.output) - - def test_get_job(self): - result = invoke_cli("get-job", "job_4") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual( - "jobID: ''\nstatus: accepted\ntype: process\n\n", result.output - ) - - def test_dismiss_job(self): - result = invoke_cli("dismiss-job", "job_4") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual( - "jobID: ''\nstatus: accepted\ntype: process\n\n", result.output - ) - - def test_get_job_results(self): - result = invoke_cli("get-job-results", "job_4") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual("null\n...\n\n", result.output) - - @classmethod - def get_result_msg(cls, result: typer.testing.Result): - if result.exit_code != 0: - return ( - f"stdout was: [{result.stdout}]\n" - f"stderr was: [{result.stderr}]\n" - f"exception was: {result.exception}" - ) - else: - return None - - -class CliWithRealClientTest(TestCase): - def test_get_processes(self): - """Test code in app so that the non-mocked Client is used.""" - runner = typer.testing.CliRunner() - result = runner.invoke(cli, ["list-processes"]) - # May succeed if dev server is running - self.assertTrue( - result.exit_code in (0, 1, 3), msg=f"exit code was {result.exit_code}" - ) - if result.exit_code != 0: - print(result.output) diff --git a/s2gos-client/src/tests/cli/test_client.py b/s2gos-client/src/tests/cli/test_client.py deleted file mode 100644 index 31d54f7..0000000 --- a/s2gos-client/src/tests/cli/test_client.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -import click -import pytest -import typer - -from s2gos_client import ClientError -from s2gos_client.api.client import Client -from s2gos_client.api.transport import TransportError -from s2gos_client.cli.cli import cli -from s2gos_client.cli.client import use_client -from s2gos_common.models import ApiError - - -class UseClientTest(TestCase): - def test_success(self): - with use_client(new_cli_context(), None) as client: - self.assertIsInstance(client, Client) - - # noinspection PyMethodMayBeStatic - def test_fail_with_client_error(self): - with pytest.raises(click.exceptions.Exit): - with use_client(new_cli_context(), None): - raise ClientError( - "Not found", - api_error=ApiError( - type="error", - title="Not found", - status=404, - detail="Something was not found", - traceback=["a", "b", "c"], - ), - ) - - # noinspection PyMethodMayBeStatic - def test_fail_with_client_error_and_traceback(self): - with pytest.raises(ClientError, match="Not found"): - with use_client(new_cli_context(traceback=True), None): - raise ClientError( - "Not found", - api_error=ApiError( - type="error", - title="Not found", - status=404, - detail="Something was not found", - traceback=["a", "b", "c"], - ), - ) - - # noinspection PyMethodMayBeStatic - def test_fail_with_transport_error(self): - with pytest.raises(click.exceptions.Exit): - with use_client(new_cli_context(), None): - raise TransportError("connection could not be established") - - # noinspection PyMethodMayBeStatic - def test_fail_with_transport_error_and_traceback(self): - with pytest.raises(TransportError, match="connection could not be established"): - with use_client(new_cli_context(traceback=True), None): - raise TransportError("connection could not be established") - - # noinspection PyMethodMayBeStatic - def test_fail_with_other_error(self): - with pytest.raises(ValueError, match=r"path must be given"): - with use_client(new_cli_context(), None): - raise ValueError("path must be given") - - -def new_cli_context(traceback: bool = False): - return typer.Context( - cli, - obj={ - "get_client": lambda config_path: Client(config_path=config_path), - "traceback": traceback, - }, - # the following have no special meaning for the tests, - # but typer/click wants them to be given. - allow_extra_args=False, - allow_interspersed_args=False, - ignore_unknown_options=False, - ) diff --git a/s2gos-client/src/tests/cli/test_config.py b/s2gos-client/src/tests/cli/test_config.py deleted file mode 100644 index a8c239d..0000000 --- a/s2gos-client/src/tests/cli/test_config.py +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import os -import unittest -from pathlib import Path -from unittest.mock import patch - -import click -import pytest - -from s2gos_client import ClientConfig -from s2gos_client.api.defaults import DEFAULT_CONFIG_PATH -from s2gos_client.cli.config import configure_client, get_config -from s2gos_common.util.testing import set_env, set_env_cm - -DEFAULT_CONFIG_BACKUP_PATH = DEFAULT_CONFIG_PATH.parent / ( - str(DEFAULT_CONFIG_PATH.name) + ".backup" -) - - -class ReadConfigTest(unittest.TestCase): - def setUp(self): - self.restore_env = set_env( - **{k: None for k, v in os.environ.items() if k.startswith("S2GOS_")} - ) - self.must_restore_config = False - # If a config backup exists, delete it - if DEFAULT_CONFIG_BACKUP_PATH.exists(): - os.remove(DEFAULT_CONFIG_BACKUP_PATH) - # If default config exists, rename it into the backup config - if DEFAULT_CONFIG_PATH.exists(): - DEFAULT_CONFIG_PATH.rename(DEFAULT_CONFIG_BACKUP_PATH) - - def tearDown(self): - self.restore_env() - # If config backup exists, rename it into the default - if DEFAULT_CONFIG_BACKUP_PATH.exists(): - # If default config exists, remove it, - # so we can rename the backup - if DEFAULT_CONFIG_PATH.exists(): - os.remove(DEFAULT_CONFIG_PATH) - DEFAULT_CONFIG_BACKUP_PATH.rename(DEFAULT_CONFIG_PATH) - - # noinspection PyMethodMayBeStatic - def test_get_config_custom(self): - with pytest.raises( - click.ClickException, - match="Configuration file fantasia.cfg not found or empty.", - ): - get_config("fantasia.cfg") - - # noinspection PyMethodMayBeStatic - def test_get_config_no_default(self): - with pytest.raises( - click.ClickException, - match=( - r"The client tool has not yet been configured; " - r"please use the 'configure' command to set it up\." - ), - ): - get_config(None) - - @patch("typer.prompt") - def test_configure_client_default(self, mock_prompt): - mock_prompt.side_effect = ["bibo", "ip245", "http://localhorst:9999"] - actual_config_path = configure_client() - self.assertEqual(DEFAULT_CONFIG_PATH, actual_config_path) - self.assertTrue(DEFAULT_CONFIG_PATH.exists()) - config = get_config(None) - self.assertEqual( - ClientConfig( - user_name="bibo", - access_token="ip245", - server_url="http://localhorst:9999", - ), - config, - ) - - @patch("typer.prompt") - def test_configure_client_custom(self, mock_prompt): - # Simulate sequential responses to typer.prompt - mock_prompt.side_effect = ["bert", "s3cr3t", "http://localhorst:9090"] - custom_config_path = Path("test.cfg") - try: - actual_config_path = configure_client(config_path=custom_config_path) - self.assertEqual(custom_config_path, actual_config_path) - self.assertTrue(custom_config_path.exists()) - config = get_config(custom_config_path) - self.assertEqual( - ClientConfig( - user_name="bert", - access_token="s3cr3t", - server_url="http://localhorst:9090", - ), - config, - ) - finally: - if custom_config_path.exists(): - os.remove(custom_config_path) - - @patch("typer.prompt") - def test_configure_client_use_defaults(self, mock_prompt): - # Simulate sequential responses to typer.prompt - with set_env_cm( - S2GOS_USER_NAME="bibo", - S2GOS_ACCESS_TOKEN="9823hc", - S2GOS_SERVER_URL="http://localhorst:2357", - ): - mock_prompt.side_effect = ["bibo", "*****", "http://localhorst:2357"] - custom_config_path = Path("test.cfg") - try: - actual_config_path = configure_client(config_path=custom_config_path) - self.assertEqual(custom_config_path, actual_config_path) - self.assertTrue(custom_config_path.exists()) - config = get_config(custom_config_path) - self.assertEqual( - ClientConfig( - user_name="bibo", - access_token="9823hc", - server_url="http://localhorst:2357", - ), - config, - ) - finally: - if custom_config_path.exists(): - os.remove(custom_config_path) diff --git a/s2gos-client/src/tests/cli/test_output.py b/s2gos-client/src/tests/cli/test_output.py deleted file mode 100644 index 3ce4597..0000000 --- a/s2gos-client/src/tests/cli/test_output.py +++ /dev/null @@ -1,263 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -from s2gos_client.cli.output import OutputFormat, OutputRenderer, get_renderer -from s2gos_common.models import ( - JobInfo, - JobList, - JobResults, - JobStatus, - JobType, - ProcessDescription, - ProcessList, - ProcessSummary, -) -from s2gos_common.process.request import ExecutionRequest - - -class OutputTest(TestCase): - def test_simple(self): - outputs = get_outputs(get_renderer(OutputFormat.simple)) - self.assertEqual( - { - "render_job": ( - "Job ID: job_8\n" - "Process ID: primes_between\n" - "Status: JobStatus.running\n" - "Progress: None\n" - "Message: None\n" - "Created at: None\n" - "Started at: None\n" - "Updated at: None\n" - "Ended at: None" - ), - "render_job_list": "1: job_8 - JobStatus.running - None - None", - "render_job_list_empty": "No jobs available.", - "render_job_results": ( - "return_value:\n- 2\n- 3\n- 5\n- 7\n- 11\n- 13\n" - ), - "render_process_description": ( - "id: primes_between\n" - "inputs:\n" - " max_val:\n" - " schema:\n" - " type: integer\n" - " title: Maximum value\n" - " min_val:\n" - " schema:\n" - " type: integer\n" - " title: Minimum value\n" - "version: 1.4.0\n" - ), - "render_process_list": "1: primes_between - None", - "render_process_list_empty": "No processes available.", - "render_execution_request_valid": ( - "Execution request is valid:\n" - "inputs:\n" - " max_val: 20\n" - " min_val: 0\n" - "process_id: primes_between\n" - ), - }, - outputs, - ) - - def test_yaml(self): - outputs = get_outputs(get_renderer(OutputFormat.yaml)) - self.assertEqual( - { - "render_job": ( - "jobID: job_8\n" - "processID: primes_between\n" - "status: running\n" - "type: process\n" - ), - "render_job_list": ( - "jobs:\n" - "- jobID: job_8\n" - " processID: primes_between\n" - " status: running\n" - " type: process\n" - "links: []\n" - ), - "render_job_list_empty": "jobs: []\nlinks: []\n", - "render_job_results": ( - "return_value:\n- 2\n- 3\n- 5\n- 7\n- 11\n- 13\n" - ), - "render_process_description": ( - "id: primes_between\n" - "inputs:\n" - " max_val:\n" - " schema:\n" - " type: integer\n" - " title: Maximum value\n" - " min_val:\n" - " schema:\n" - " type: integer\n" - " title: Minimum value\n" - "version: 1.4.0\n" - ), - "render_process_list": ( - "links: []\nprocesses:\n- id: primes_between\n version: 1.4.0\n" - ), - "render_process_list_empty": "links: []\nprocesses: []\n", - "render_execution_request_valid": ( - "inputs:\n max_val: 20\n min_val: 0\nprocess_id: primes_between\n" - ), - }, - outputs, - ) - - def test_json(self): - outputs = get_outputs(get_renderer(OutputFormat.json)) - self.assertEqual( - { - "render_job": ( - "{\n" - ' "processID": "primes_between",\n' - ' "type": "process",\n' - ' "jobID": "job_8",\n' - ' "status": "running"\n' - "}" - ), - "render_job_list": ( - "{\n" - ' "jobs": [\n' - " {\n" - ' "processID": "primes_between",\n' - ' "type": "process",\n' - ' "jobID": "job_8",\n' - ' "status": "running"\n' - " }\n" - " ],\n" - ' "links": []\n' - "}" - ), - "render_job_list_empty": '{\n "jobs": [],\n "links": []\n}', - "render_job_results": ( - "{\n" - ' "return_value": [\n' - " 2,\n" - " 3,\n" - " 5,\n" - " 7,\n" - " 11,\n" - " 13\n" - " ]\n" - "}" - ), - "render_process_description": ( - "{\n" - ' "id": "primes_between",\n' - ' "version": "1.4.0",\n' - ' "inputs": {\n' - ' "min_val": {\n' - ' "title": "Minimum value",\n' - ' "schema": {\n' - ' "type": "integer"\n' - " }\n" - " },\n" - ' "max_val": {\n' - ' "title": "Maximum value",\n' - ' "schema": {\n' - ' "type": "integer"\n' - " }\n" - " }\n" - " }\n" - "}" - ), - "render_process_list": ( - "{\n" - ' "processes": [\n' - " {\n" - ' "id": "primes_between",\n' - ' "version": "1.4.0"\n' - " }\n" - " ],\n" - ' "links": []\n' - "}" - ), - "render_process_list_empty": '{\n "processes": [],\n "links": []\n}', - "render_execution_request_valid": ( - "{\n" - ' "inputs": {\n' - ' "min_val": 0,\n' - ' "max_val": 20\n' - " },\n" - ' "process_id": "primes_between"\n' - "}" - ), - }, - outputs, - ) - - -def get_outputs(renderer: OutputRenderer) -> dict[str, str]: - return { - "render_process_list": renderer.render_process_list( - ProcessList( - processes=[ProcessSummary(id="primes_between", version="1.4.0")], - links=[], - ) - ), - "render_process_list_empty": renderer.render_process_list( - ProcessList( - processes=[], - links=[], - ) - ), - "render_process_description": renderer.render_process_description( - ProcessDescription( - id="primes_between", - version="1.4.0", - inputs={ - "min_val": { - "title": "Minimum value", - "schema": {"type": "integer"}, - }, - "max_val": { - "title": "Maximum value", - "schema": {"type": "integer"}, - }, - }, - ), - ), - "render_execution_request_valid": renderer.render_execution_request_valid( - ExecutionRequest( - process_id="primes_between", inputs={"min_val": 0, "max_val": 20} - ) - ), - "render_job_list": renderer.render_job_list( - JobList( - jobs=[ - JobInfo( - processID="primes_between", - jobID="job_8", - type=JobType.process, - status=JobStatus.running, - ) - ], - links=[], - ) - ), - "render_job_list_empty": renderer.render_job_list( - JobList( - jobs=[], - links=[], - ) - ), - "render_job": renderer.render_job_info( - JobInfo( - processID="primes_between", - jobID="job_8", - type=JobType.process, - status=JobStatus.running, - ) - ), - "render_job_results": renderer.render_job_results( - JobResults(**{"return_value": [2, 3, 5, 7, 11, 13]}) - ), - } diff --git a/s2gos-client/src/tests/gui/__init__.py b/s2gos-client/src/tests/gui/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-client/src/tests/gui/component/__init__.py b/s2gos-client/src/tests/gui/component/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-client/src/tests/gui/component/test_component.py b/s2gos-client/src/tests/gui/component/test_component.py deleted file mode 100644 index f91a9c3..0000000 --- a/s2gos-client/src/tests/gui/component/test_component.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -import panel as pn -import pytest - -from s2gos_client.gui.component import Component, JsonDateCodec, WidgetComponent - - -class ComponentTest(TestCase): - def test_defaults(self): - widget = pn.widgets.TextInput(name="Test", value="output.zarr") - component = Component(widget) - self.assertIs(widget, component.viewable) - with pytest.raises(NotImplementedError): - component.get_value() - with pytest.raises(NotImplementedError): - component.set_value(None) - with pytest.raises(NotImplementedError): - component.watch_value(lambda event: None) - - -class WidgetComponentTest(TestCase): - def test_basics(self): - widget = pn.widgets.TextInput(name="Test", value="output.zarr") - component = WidgetComponent(widget) - self.assertIs(widget, component.widget) - self.assertIs(widget, component.viewable) - self.assertEqual("output.zarr", component.get_json_value()) - self.assertEqual("output.zarr", component.get_value()) - - def test_with_codec(self): - json_codec = JsonDateCodec() - value = json_codec.from_json("2025-06-07") - widget = pn.widgets.DatePicker(name="Test", value=value) - component = WidgetComponent(widget, json_codec=json_codec) - self.assertEqual("2025-06-07", component.get_json_value()) - self.assertEqual(value, component.get_value()) - component.set_json_value("2025-06-08") - self.assertEqual("2025-06-08", component.get_json_value()) - self.assertEqual(json_codec.from_json("2025-06-08"), component.get_value()) - - def test_can_watch(self): - widget = pn.widgets.TextInput(name="Test", value="output.zarr") - component = WidgetComponent(widget) - - last_value = None - - def on_value_change(event): - nonlocal last_value - last_value = event.new - - component.watch_value(on_value_change) - component.set_json_value("output.nc") - - self.assertEqual("output.nc", last_value) - self.assertEqual("output.nc", component.get_json_value()) diff --git a/s2gos-client/src/tests/gui/component/test_container.py b/s2gos-client/src/tests/gui/component/test_container.py deleted file mode 100644 index a3de11a..0000000 --- a/s2gos-client/src/tests/gui/component/test_container.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -import panel as pn - -from s2gos_client.gui.component import ComponentContainer -from s2gos_common.models import InputDescription, Schema - - -class ComponentContainerTest(TestCase): - def test_basics(self): - container = ComponentContainer.from_input_descriptions( - { - "a_string": InputDescription( - title="String X", - description="A string", - schema=Schema(type="string"), - ) - }, - {"a_string": "bert"}, - ) - self.assertIsInstance(container, ComponentContainer) - components = container.get_components() - self.assertIsInstance(components, list) - self.assertEqual(1, len(components)) - component = components[0] - self.assertIsInstance(component.viewable, pn.widgets.Widget) - - self.assertDictEqual({"a_string": "bert"}, container.get_json_values()) - self.assertEqual("bert", component.viewable.value) - - container.set_json_values({"a_string": "bibo"}) - self.assertDictEqual({"a_string": "bibo"}, container.get_json_values()) - self.assertEqual("bibo", component.viewable.value) diff --git a/s2gos-client/src/tests/gui/component/test_factory.py b/s2gos-client/src/tests/gui/component/test_factory.py deleted file mode 100644 index 13e73cc..0000000 --- a/s2gos-client/src/tests/gui/component/test_factory.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -import panel as pn -import pytest - -from s2gos_client.gui.component import ( - Component, - ComponentFactoryBase, - JsonSchemaDict, - JsonValue, -) - - -class MockFactory(ComponentFactoryBase): - def create_component( - self, json_value: JsonValue, title: str, schema: JsonSchemaDict - ) -> Component: - return Component(pn.widgets.TextInput(value=json_value, name=title)) - - -class MockRegistry: - def __init__(self): - self.registrations = [] - - def register_factory(self, *args, **kwargs): - self.registrations.append((args, kwargs)) - - -class ComponentFactoryTest(TestCase): - def test_get_score_type_and_format(self): - class Factory2(MockFactory): - type = "array" - format = "bbox" - - f2 = Factory2() - self.assertEqual(False, f2.accept(dict())) - self.assertEqual(False, f2.accept(dict(type="integer"))) - self.assertEqual(False, f2.accept(dict(type="array"))) - self.assertEqual(True, f2.accept(dict(type="array", format="bbox"))) - self.assertEqual(False, f2.accept(dict(format="bbox"))) - - def test_get_score_type_only(self): - class Factory1(MockFactory): - type = "string" - - f1 = Factory1() - self.assertEqual(False, f1.accept(dict())) - self.assertEqual(False, f1.accept(dict(type="integer"))) - self.assertEqual(True, f1.accept(dict(type="string"))) - self.assertEqual(False, f1.accept(dict(type="string", format="date"))) - self.assertEqual(False, f1.accept(dict(format="date"))) - - def test_get_score_format_only(self): - class Factory(MockFactory): - format = "point" - - f = Factory() - self.assertEqual(False, f.accept(dict())) - self.assertEqual(False, f.accept(dict(format="bbox"))) - self.assertEqual(True, f.accept(dict(format="point"))) - self.assertEqual(False, f.accept(dict(type="integer", format="point"))) - self.assertEqual(False, f.accept(dict(type="number"))) - - # noinspection PyMethodMayBeStatic,PyTypeChecker - def test_register_in(self): - class GoodFactory0(MockFactory): - pass - - class GoodFactory1(MockFactory): - type = "string" - - class GoodFactory2(MockFactory): - type = "integer" - - class GoodFactory3(MockFactory): - type = "boolean" - format = "*" - - def accept(self, schema: JsonSchemaDict) -> bool: - return schema.get("format") in ("bistate", "tristate") - - registry = MockRegistry() - GoodFactory0.register_in(registry) - GoodFactory1.register_in(registry) - GoodFactory2.register_in(registry) - GoodFactory3.register_in(registry) - self.assertEqual( - [ - {"format": None, "type": None}, - {"format": None, "type": "string"}, - {"format": None, "type": "integer"}, - {"format": "*", "type": "boolean"}, - ], - [kwargs for _args, kwargs in registry.registrations], - ) - self.assertIsInstance(registry.registrations[0][0][0], GoodFactory0) - self.assertIsInstance(registry.registrations[1][0][0], GoodFactory1) - self.assertIsInstance(registry.registrations[2][0][0], GoodFactory2) - self.assertIsInstance(registry.registrations[3][0][0], GoodFactory3) - - # noinspection PyMethodMayBeStatic - def test_raise_on_missing_accept(self): - class FactoryWithoutOwnAccept(MockFactory): - type = "string" - format = "*" - - with pytest.raises( - TypeError, - match=( - r"class FactoryWithoutOwnAccept must override method " - r"ComponentFactoryBase\.accept\(\)" - ), - ): - FactoryWithoutOwnAccept() - - # noinspection PyMethodMayBeStatic - def test_raise_on_wrong_type(self): - class FactoryWithWrongTypeName(MockFactory): - type = "strong" - - with pytest.raises( - ValueError, - match=( - "value of ComponentFactoryBase.type must be one of " - "'boolean', 'integer', 'number', 'string', 'array', 'object', " - "but was 'strong'" - ), - ): - FactoryWithWrongTypeName() diff --git a/s2gos-client/src/tests/gui/component/test_registry.py b/s2gos-client/src/tests/gui/component/test_registry.py deleted file mode 100644 index d8bf79d..0000000 --- a/s2gos-client/src/tests/gui/component/test_registry.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -import panel as pn - -from s2gos_client.gui.component import ( - Component, - ComponentFactoryBase, - ComponentFactoryRegistry, - JsonSchemaDict, - JsonValue, -) - - -class MockFactory(ComponentFactoryBase): - def create_component( - self, json_value: JsonValue, title: str, schema: JsonSchemaDict - ) -> Component: - return Component(pn.widgets.TextInput(value=json_value, name=title)) - - -class ComponentFactoryRegistryTest(TestCase): - def test_register_and_find(self): - class Factory0(MockFactory): - pass - - class Factory1(MockFactory): - type = "string" - - class Factory2(MockFactory): - type = "array" - format = "bbox" - - registry = ComponentFactoryRegistry() - - factory = registry.find_factory(dict(type="string")) - self.assertIsNone(factory) - - Factory0.register_in(registry) - Factory2.register_in(registry) - Factory1.register_in(registry) - - factory = registry.find_factory(dict()) - self.assertIsInstance(factory, Factory0) - - factory = registry.find_factory(dict(type="string")) - self.assertIsInstance(factory, Factory1) - - factory = registry.find_factory(dict(type="array")) - self.assertIsNone(factory) - - factory = registry.find_factory(dict(type="array", format="bbox")) - self.assertIsInstance(factory, Factory2) diff --git a/s2gos-client/src/tests/gui/test_client.py b/s2gos-client/src/tests/gui/test_client.py deleted file mode 100644 index 32de9d2..0000000 --- a/s2gos-client/src/tests/gui/test_client.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Any -from unittest import TestCase - -from s2gos_client.api.transport import Transport, TransportArgs -from s2gos_client.gui import Client as GuiClient -from s2gos_client.gui.jobs_panel import JobsPanel -from s2gos_client.gui.main_panel import MainPanel -from s2gos_common.models import JobList, ProcessList - - -class ClientTest(TestCase): - def test_show_processes(self): - class _MockTransport(Transport): - def call(self, args: TransportArgs) -> Any: - if (args.method, args.path) == ("get", "/processes"): - return ProcessList(processes=[], links=[]) - return None - - client = GuiClient(_transport=_MockTransport()) - processes_form = client.show() - self.assertIsInstance(processes_form, MainPanel) - - def test_show_jobs(self): - class _MockTransport(Transport): - def call(self, args: TransportArgs) -> Any: - if (args.method, args.path) == ("get", "/jobs"): - return JobList(jobs=[], links=[]) - return None - - client = GuiClient(_transport=_MockTransport()) - jobs_form = client.show_jobs() - self.assertIsInstance(jobs_form, JobsPanel) diff --git a/s2gos-client/src/tests/gui/test_jobs_info_panel.py b/s2gos-client/src/tests/gui/test_jobs_info_panel.py deleted file mode 100644 index bdbf196..0000000 --- a/s2gos-client/src/tests/gui/test_jobs_info_panel.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -from panel.layout import Panel - -from s2gos_client.gui.job_info_panel import JobInfoPanel -from s2gos_client.gui.jobs_observer import JobsObserver - - -class JobInfoPanelTest(TestCase): - def test_with_date_input(self): - job_info_panel = JobInfoPanel() - self.assertIsInstance(job_info_panel.__panel__(), Panel) - - def test_is_observer(self): - job_info_panel = JobInfoPanel() - self.assertIsInstance(job_info_panel, JobsObserver) diff --git a/s2gos-client/src/tests/gui/test_jobs_panel.py b/s2gos-client/src/tests/gui/test_jobs_panel.py deleted file mode 100644 index aee5639..0000000 --- a/s2gos-client/src/tests/gui/test_jobs_panel.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -from panel.layout import Panel - -from s2gos_client.gui.jobs_observer import JobsObserver -from s2gos_client.gui.jobs_panel import JobsPanel -from s2gos_common.models import JobInfo, JobList, JobStatus, JobType - - -class JobsFormTest(TestCase): - def test_it(self): - jobs_panel = _create_jobs_form() - self.assertIsInstance(jobs_panel.__panel__(), Panel) - - def test_is_observer(self): - jobs_form = _create_jobs_form() - self.assertIsInstance(jobs_form, JobsObserver) - - -def _create_jobs_form() -> JobsPanel: - job_list = JobList( - jobs=[ - JobInfo( - type=JobType.process, - processID="gen_scene", - jobID="job_1", - status=JobStatus.successful, - progress=100, - ), - JobInfo( - type=JobType.process, - processID="gen_scene", - jobID="job_2", - status=JobStatus.running, - progress=23, - ), - JobInfo( - type=JobType.process, - processID="gen_scene", - jobID="job_3", - status=JobStatus.failed, - progress=97, - ), - JobInfo( - type=JobType.process, - processID="gen_scene", - jobID="job_4", - status=JobStatus.accepted, - ), - ], - links=[], - ) - - def on_delete_job(job_id: str): - pass - - def on_cancel_job(job_id: str): - pass - - def on_restart_job(job_id: str): - pass - - def on_get_job_results(job_id: str): - pass - - panel = JobsPanel( - on_delete_job=on_delete_job, - on_cancel_job=on_cancel_job, - on_restart_job=on_restart_job, - on_get_job_results=on_get_job_results, - ) - panel.on_job_list_changed(job_list) - return panel diff --git a/s2gos-client/src/tests/gui/test_main_panel.py b/s2gos-client/src/tests/gui/test_main_panel.py deleted file mode 100644 index d35a461..0000000 --- a/s2gos-client/src/tests/gui/test_main_panel.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -from panel.layout import Panel - -from s2gos_client.gui.jobs_observer import JobsObserver -from s2gos_client.gui.main_panel import MainPanel -from s2gos_common.models import ( - InputDescription, - JobInfo, - JobStatus, - JobType, - ProcessDescription, - ProcessList, - ProcessRequest, - Schema, -) - -bbox_input = InputDescription( - title="Bounding box", - schema=Schema.model_validate( - { - "type": "array", - "items": {"type": "number"}, - "format": "bbox", - } - ), -) - -date_input = InputDescription( - title="Date", - schema=Schema.model_validate( - { - "type": "string", - "format": "date", - "default": "2025-01-01", - } - ), -) - -int_input = InputDescription( - title="Periodicity", - schema=Schema.model_validate( - { - "type": "integer", - "minimum": 1, - "maximum": 10, - }, - ), -) - - -class MainFormTest(TestCase): - def test_is_observer(self): - main_panel = _create_main_panel({}) - self.assertIsInstance(main_panel, JobsObserver) - - def test_with_int_input(self): - main_panel = _create_main_panel({"periodicity": int_input}) - self.assertIsInstance(main_panel.__panel__(), Panel) - - def test_with_bbox_input(self): - main_panel = _create_main_panel({"bbox": bbox_input}) - self.assertIsInstance(main_panel.__panel__(), Panel) - - def test_with_date_input(self): - main_panel = _create_main_panel({"date": date_input}) - self.assertIsInstance(main_panel.__panel__(), Panel) - - -def _create_main_panel(process_inputs: dict[str, InputDescription]) -> MainPanel: - process = ProcessDescription( - id="gen_scene", - title="Generate a scene", - version="1", - inputs=process_inputs, - ) - - def on_get_process(_process_id: str): - return process - - def on_execute_process(process_id: str, _request: ProcessRequest): - return JobInfo( - processID=process_id, - jobID="job_8", - type=JobType.process, - status=JobStatus.successful, - ) - - process_list = ProcessList(processes=[process], links=[]) - - return MainPanel( - process_list, - None, - on_get_process=on_get_process, - on_execute_process=on_execute_process, - ) diff --git a/s2gos-client/src/tests/helpers.py b/s2gos-client/src/tests/helpers.py deleted file mode 100644 index fc54acf..0000000 --- a/s2gos-client/src/tests/helpers.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import inspect -from enum import Enum -from types import NoneType -from typing import Any - -import pydantic -from pydantic import BaseModel -from pydantic.fields import FieldInfo -from pydantic_core import PydanticUndefined - -from s2gos_client.api.transport import AsyncTransport, Transport, TransportArgs - - -class MockTransport(AsyncTransport, Transport): # pragma: no cover - def __init__(self): - self.calls: list[TransportArgs] = [] - self.async_calls: list[TransportArgs] = [] - self.closed = False - self.id_counter = 0 - - def new_id(self): - self.id_counter += 1 - return f"ID-{self.id_counter}" - - def call(self, args: TransportArgs) -> Any: - self.calls.append(args) - return self._create_model_object(args) - - async def async_call(self, args: TransportArgs) -> Any: - self.async_calls.append(args) - return self._create_model_object(args) - - def _create_model_object(self, args: TransportArgs) -> Any: - return_type = args.return_types.get("200", args.return_types.get("201")) - return self.new_default_value(return_type) if return_type is not None else None - - def close(self): - self.closed = True - - async def async_close(self): - self.closed = True - - def new_default_value(self, t: type) -> Any: - # args = get_args(t) - # t = get_origin(t) - defaults: dict[type, Any] = { - Any: None, - NoneType: None, - bool: False, - bytes: b"", - dict: {}, - float: 0.0, - int: 0, - list: [], - tuple: (), - set: set(), - str: "", - } - if t in defaults: - return defaults[t] - if inspect.isclass(t) and issubclass(t, Enum): - return next(iter(t)) - if inspect.isclass(t) and issubclass(t, BaseModel): - model_cls: type[pydantic.BaseModel] = t - # noinspection PyTypeChecker - fields: dict[str, FieldInfo] = model_cls.model_fields - kwargs = { - k: ( - v.default - if v.default is not PydanticUndefined - else ( - self.new_id() - if k == "id" - else ( - v.default_factory() - if v.default_factory is not None - else self.new_default_value(v.annotation) - ) - ) - ) - for k, v in fields.items() - } - return t(**kwargs) - return t() diff --git a/s2gos-client/src/s2gos_client/api/transport/__init__.py b/s2gos-client/src/tests/test_api.py similarity index 51% rename from s2gos-client/src/s2gos_client/api/transport/__init__.py rename to s2gos-client/src/tests/test_api.py index 0982b90..ede2fc8 100644 --- a/s2gos-client/src/s2gos_client/api/transport/__init__.py +++ b/s2gos-client/src/tests/test_api.py @@ -2,7 +2,10 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -from .args import TransportArgs -from .transport import AsyncTransport, Transport, TransportError +import s2gos_client.api -__all__ = ["AsyncTransport", "Transport", "TransportArgs", "TransportError"] + +def test_api_ok(): + assert {"AsyncClient", "Client", "ClientConfig", "ClientError"}.issubset( + dir(s2gos_client.api) + ) diff --git a/s2gos-client/src/tests/test_cli.py b/s2gos-client/src/tests/test_cli.py new file mode 100644 index 0000000..eb050c8 --- /dev/null +++ b/s2gos-client/src/tests/test_cli.py @@ -0,0 +1,9 @@ +# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors +# Permissions are hereby granted under the terms of the Apache 2.0 License: +# https://opensource.org/license/apache-2-0. + +import s2gos_client.cli + + +def test_cli_ok(): + assert {"cli"}.issubset(dir(s2gos_client.cli)) diff --git a/s2gos-client/src/tests/test_gui.py b/s2gos-client/src/tests/test_gui.py new file mode 100644 index 0000000..e551555 --- /dev/null +++ b/s2gos-client/src/tests/test_gui.py @@ -0,0 +1,9 @@ +# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors +# Permissions are hereby granted under the terms of the Apache 2.0 License: +# https://opensource.org/license/apache-2-0. + +import s2gos_client.gui + + +def test_gui_ok(): + assert {"Client"}.issubset(dir(s2gos_client.gui)) From fc964a9d8fa66b6851eb240cf1c11f8efaeb23da Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Thu, 6 Nov 2025 18:20:19 +0100 Subject: [PATCH 03/16] Package `s2gos-app-ex` now uses the Eozilla package `procodile` --- CHANGES.md | 4 +- s2gos-app-ex/Dockerfile | 3 -- s2gos-app-ex/pixi.lock | 55 ++++++++++++++++------ s2gos-app-ex/pyproject.toml | 2 +- s2gos-app-ex/src/s2gos_app_ex/cli.py | 2 +- s2gos-app-ex/src/s2gos_app_ex/processes.py | 2 +- 6 files changed, 47 insertions(+), 21 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1173d91..3a5bb2e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,8 @@ ## Changes in version 0.0.6 (in development) -- Changed the `s2gos-client` to use the Eozilla `cuiman` package. +- Implementation code moved to [Eozilla](https://github.com/eo-tools/eozilla) (#39): + - Package `s2gos-client` now uses the Eozilla package `cuiman`. + - Package `s2gos-app-ex` now uses the Eozilla package `procodile`. ## Changes in version 0.0.5 diff --git a/s2gos-app-ex/Dockerfile b/s2gos-app-ex/Dockerfile index 5ba5134..d19be98 100644 --- a/s2gos-app-ex/Dockerfile +++ b/s2gos-app-ex/Dockerfile @@ -1,9 +1,7 @@ # Stage 1 --------------------------- FROM ghcr.io/prefix-dev/pixi:0.50.2-bookworm-slim AS build WORKDIR /app -RUN mkdir s2gos-common RUN mkdir s2gos-app-ex -COPY ./s2gos-common ./s2gos-common COPY ./s2gos-app-ex ./s2gos-app-ex RUN cd ./s2gos-app-ex && pixi install --locked -e production RUN cd ./s2gos-app-ex && pixi shell-hook -e production -s bash > /shell-hook @@ -15,7 +13,6 @@ RUN echo 'exec "$@"' >> /app/entrypoint.sh FROM ubuntu:24.04 AS production WORKDIR /app COPY --from=build /app/s2gos-app-ex/.pixi/envs/production /app/s2gos-app-ex/.pixi/envs/production -COPY --from=build /app/s2gos-common/src /app/s2gos-common/src COPY --from=build /app/s2gos-app-ex/src /app/s2gos-app-ex/src COPY --from=build --chmod=0755 /app/entrypoint.sh /app/entrypoint.sh ENTRYPOINT [ "/app/entrypoint.sh" ] diff --git a/s2gos-app-ex/pixi.lock b/s2gos-app-ex/pixi.lock index 4c2bc50..ebce1a0 100644 --- a/s2gos-app-ex/pixi.lock +++ b/s2gos-app-ex/pixi.lock @@ -64,7 +64,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.1-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - pypi: ../s2gos-common + - pypi: https://files.pythonhosted.org/packages/8a/6d/f596954df87cfa05b82a9f7f2bbda486b40465378c978998f06058eecdfa/gavicore-0.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/35/53/f31ab23c29a5a25084948774ee4a43d02d8b1076e8498de9152afda62768/procodile-0.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: ./ win-64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda @@ -114,7 +116,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_31.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_31.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_31.conda - - pypi: ../s2gos-common + - pypi: https://files.pythonhosted.org/packages/8a/6d/f596954df87cfa05b82a9f7f2bbda486b40465378c978998f06058eecdfa/gavicore-0.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/35/53/f31ab23c29a5a25084948774ee4a43d02d8b1076e8498de9152afda62768/procodile-0.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl - pypi: ./ production: channels: @@ -164,7 +168,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.1-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - pypi: ../s2gos-common + - pypi: https://files.pythonhosted.org/packages/8a/6d/f596954df87cfa05b82a9f7f2bbda486b40465378c978998f06058eecdfa/gavicore-0.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/35/53/f31ab23c29a5a25084948774ee4a43d02d8b1076e8498de9152afda62768/procodile-0.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: ./ win-64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda @@ -199,7 +205,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_31.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_31.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_31.conda - - pypi: ../s2gos-common + - pypi: https://files.pythonhosted.org/packages/8a/6d/f596954df87cfa05b82a9f7f2bbda486b40465378c978998f06058eecdfa/gavicore-0.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/35/53/f31ab23c29a5a25084948774ee4a43d02d8b1076e8498de9152afda62768/procodile-0.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl - pypi: ./ packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -353,6 +361,14 @@ packages: - pkg:pypi/exceptiongroup?source=hash-mapping size: 21284 timestamp: 1746947398083 +- pypi: https://files.pythonhosted.org/packages/8a/6d/f596954df87cfa05b82a9f7f2bbda486b40465378c978998f06058eecdfa/gavicore-0.0.7-py3-none-any.whl + name: gavicore + version: 0.0.7 + sha256: a357a02d07607e60f11e64440282b08045c6b001aabdcb9dee1aba9460c4c23e + requires_dist: + - pydantic + - typer + requires_python: '>=3.10' - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda sha256: 71e750d509f5fa3421087ba88ef9a7b9be11c53174af3aa4d06aff4c18b38e8e md5: 8b189310083baabfb622af68fd9d3ae3 @@ -749,6 +765,16 @@ packages: - pkg:pypi/pluggy?source=hash-mapping size: 24246 timestamp: 1747339794916 +- pypi: https://files.pythonhosted.org/packages/35/53/f31ab23c29a5a25084948774ee4a43d02d8b1076e8498de9152afda62768/procodile-0.0.7-py3-none-any.whl + name: procodile + version: 0.0.7 + sha256: 7e50cf0f94cec1e1e796ddf18b49c2b2c3b8464f919472a96090f37abca86106 + requires_dist: + - gavicore>=0.0.7 + - pydantic + - pyyaml + - typer + requires_python: '>=3.10' - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.0.0-py312h66e93f0_0.conda sha256: 158047d7a80e588c846437566d0df64cec5b0284c7184ceb4f3c540271406888 md5: 8e30db4239508a538e4a3b3cdf5b9616 @@ -935,6 +961,16 @@ packages: purls: [] size: 6958 timestamp: 1752805918820 +- pypi: https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl + name: pyyaml + version: 6.0.3 + sha256: 5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: pyyaml + version: 6.0.3 + sha256: ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc + requires_python: '>=3.8' - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda sha256: 2d6d0c026902561ed77cd646b5021aef2d4db22e57a5b0178dfc669231e06d2c md5: 283b96675859b20a825f8fa30f311446 @@ -993,16 +1029,7 @@ packages: - pypi: ./ name: s2gos-app-ex version: 0.0.0 - sha256: bcf9b35cf8dde8c393c51de92d933cf68c3f7e57765e239c71fadf6e0da497fa - requires_python: '>=3.10' - editable: true -- pypi: ../s2gos-common - name: s2gos-common - version: 0.0.4.dev0 - sha256: 18e640e32d505210d7bb0fbdf5695ca668a41489aa84cc5f41aa4fe658247c77 - requires_dist: - - pydantic - - typer + sha256: fe053f016670ef03d9da693a3bfc9b912ad8dcb5dfe429ca625ffd59a768cc7d requires_python: '>=3.10' editable: true - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_1.conda diff --git a/s2gos-app-ex/pyproject.toml b/s2gos-app-ex/pyproject.toml index b24081f..b4e3e87 100644 --- a/s2gos-app-ex/pyproject.toml +++ b/s2gos-app-ex/pyproject.toml @@ -51,7 +51,7 @@ typer = ">=0.16.0,<0.17" pydantic = ">=2.11.7,<3" [tool.pixi.pypi-dependencies] -s2gos-common = { path = "../s2gos-common", editable = true } +procodile = ">=0.0.7" s2gos-app-ex = { path = ".", editable = true } [tool.pixi.feature.dev.dependencies] diff --git a/s2gos-app-ex/src/s2gos_app_ex/cli.py b/s2gos-app-ex/src/s2gos_app_ex/cli.py index 32afdf1..13b134b 100644 --- a/s2gos-app-ex/src/s2gos_app_ex/cli.py +++ b/s2gos-app-ex/src/s2gos_app_ex/cli.py @@ -2,7 +2,7 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -from s2gos_common.process import get_cli +from procodile.cli import get_cli # The CLI with a basic set of commands. # The `cli` is a Typer application of type `typer.Typer()`, diff --git a/s2gos-app-ex/src/s2gos_app_ex/processes.py b/s2gos-app-ex/src/s2gos_app_ex/processes.py index 974d434..e63a9d3 100644 --- a/s2gos-app-ex/src/s2gos_app_ex/processes.py +++ b/s2gos-app-ex/src/s2gos_app_ex/processes.py @@ -6,7 +6,7 @@ from pydantic import Field -from s2gos_common.process import JobContext, ProcessRegistry +from procodile import JobContext, ProcessRegistry registry = ProcessRegistry() From ff3426fbd2762ae08299bfaf02b3118dcc3241d8 Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Thu, 6 Nov 2025 19:20:16 +0100 Subject: [PATCH 04/16] Package `s2gos-server` now uses the Eozilla package `wraptile` --- pixi.lock | 9 +- s2gos-client/pyproject.toml | 2 +- s2gos-client/src/s2gos_client/cli.py | 6 +- s2gos-server/pyproject.toml | 7 +- s2gos-server/src/s2gos_server/app.py | 47 --- s2gos-server/src/s2gos_server/constants.py | 12 - s2gos-server/src/s2gos_server/exceptions.py | 43 --- s2gos-server/src/s2gos_server/logging.py | 18 -- s2gos-server/src/s2gos_server/main.py | 15 - s2gos-server/src/s2gos_server/provider.py | 30 -- s2gos-server/src/s2gos_server/routes.py | 118 ------- .../src/s2gos_server/services/__init__.py | 3 - .../s2gos_server/services/airflow/__init__.py | 18 -- .../services/airflow/airflow_service.py | 298 ------------------ .../s2gos_server/services/base/__init__.py | 10 - .../services/base/service_base.py | 168 ---------- .../s2gos_server/services/local/__init__.py | 18 -- .../services/local/local_service.py | 173 ---------- .../s2gos_server/services/local/testing.py | 218 ------------- s2gos-server/src/tests/services/__init__.py | 0 .../src/tests/services/airflow/__init__.py | 3 - .../services/airflow/test_airflow_service.py | 77 ----- .../src/tests/services/base/__init__.py | 0 .../tests/services/base/test_service_base.py | 145 --------- .../src/tests/services/local/__init__.py | 3 - .../services/local/test_local_service.py | 179 ----------- .../src/tests/services/local/test_testing.py | 145 --------- s2gos-server/src/tests/test_app.py | 108 ------- s2gos-server/src/tests/test_exceptions.py | 30 -- s2gos-server/src/tests/test_main.py | 14 - s2gos-server/src/tests/test_provider.py | 43 --- 31 files changed, 14 insertions(+), 1946 deletions(-) delete mode 100644 s2gos-server/src/s2gos_server/app.py delete mode 100644 s2gos-server/src/s2gos_server/constants.py delete mode 100644 s2gos-server/src/s2gos_server/exceptions.py delete mode 100644 s2gos-server/src/s2gos_server/logging.py delete mode 100644 s2gos-server/src/s2gos_server/main.py delete mode 100644 s2gos-server/src/s2gos_server/provider.py delete mode 100644 s2gos-server/src/s2gos_server/routes.py delete mode 100644 s2gos-server/src/s2gos_server/services/__init__.py delete mode 100644 s2gos-server/src/s2gos_server/services/airflow/__init__.py delete mode 100644 s2gos-server/src/s2gos_server/services/airflow/airflow_service.py delete mode 100644 s2gos-server/src/s2gos_server/services/base/__init__.py delete mode 100644 s2gos-server/src/s2gos_server/services/base/service_base.py delete mode 100644 s2gos-server/src/s2gos_server/services/local/__init__.py delete mode 100644 s2gos-server/src/s2gos_server/services/local/local_service.py delete mode 100644 s2gos-server/src/s2gos_server/services/local/testing.py delete mode 100644 s2gos-server/src/tests/services/__init__.py delete mode 100644 s2gos-server/src/tests/services/airflow/__init__.py delete mode 100644 s2gos-server/src/tests/services/airflow/test_airflow_service.py delete mode 100644 s2gos-server/src/tests/services/base/__init__.py delete mode 100644 s2gos-server/src/tests/services/base/test_service_base.py delete mode 100644 s2gos-server/src/tests/services/local/__init__.py delete mode 100644 s2gos-server/src/tests/services/local/test_local_service.py delete mode 100644 s2gos-server/src/tests/services/local/test_testing.py delete mode 100644 s2gos-server/src/tests/test_app.py delete mode 100644 s2gos-server/src/tests/test_exceptions.py delete mode 100644 s2gos-server/src/tests/test_main.py delete mode 100644 s2gos-server/src/tests/test_provider.py diff --git a/pixi.lock b/pixi.lock index f0ab7a5..3bece08 100644 --- a/pixi.lock +++ b/pixi.lock @@ -8789,13 +8789,13 @@ packages: - pypi: ./s2gos-app-ex name: s2gos-app-ex version: 0.0.0 - sha256: bcf9b35cf8dde8c393c51de92d933cf68c3f7e57765e239c71fadf6e0da497fa + sha256: fe053f016670ef03d9da693a3bfc9b912ad8dcb5dfe429ca625ffd59a768cc7d requires_python: '>=3.10' editable: true - pypi: ./s2gos-client name: s2gos-client version: 0.0.6.dev0 - sha256: 4af47689f37dddf198bf23ce42a10fed9bc845f77a340bc8a02ac9c2c29075e1 + sha256: 6d6090cfc42bd9ee1a015f10dc18f9643b61adeb3f07ad95f0de26bc66098ef6 requires_dist: - click - pydantic @@ -8819,14 +8819,15 @@ packages: - pypi: ./s2gos-server name: s2gos-server version: 0.0.6.dev0 - sha256: 08a7d558ff0af37d676cedb5dba41345302e60a6a1d5678f2e5232adbbc01999 + sha256: 9689e8151fb46e2444a32f0e404c1bee19fd4ea5b4fe9e45ee1b72e3c60073b8 requires_dist: - fastapi - pydantic - pyyaml - typer - uvicorn - - s2gos-common>=0.0.0 + - gavicore + - wraptile requires_python: '>=3.10' editable: true - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.21-h7ab7c64_0.conda diff --git a/s2gos-client/pyproject.toml b/s2gos-client/pyproject.toml index 1b4f6cc..8bd3bc7 100644 --- a/s2gos-client/pyproject.toml +++ b/s2gos-client/pyproject.toml @@ -44,7 +44,7 @@ dependencies = [ "typer", "uri-template", "httpx", - # local dependency + # Eozilla dependencies "cuiman", "gavicore", ] diff --git a/s2gos-client/src/s2gos_client/cli.py b/s2gos-client/src/s2gos_client/cli.py index 3fc14ab..177df60 100644 --- a/s2gos-client/src/s2gos_client/cli.py +++ b/s2gos-client/src/s2gos_client/cli.py @@ -4,11 +4,13 @@ from cuiman.cli import get_cli -cli = get_cli("s2gos-client") +from s2gos_server import __version__ as version + +cli = get_cli("s2gos-client", version=version) __all__ = [ "cli", ] -if __name__ == "__main__": +if __name__ == "__main__": # pragma: no cover cli() diff --git a/s2gos-server/pyproject.toml b/s2gos-server/pyproject.toml index 73725fc..815de06 100644 --- a/s2gos-server/pyproject.toml +++ b/s2gos-server/pyproject.toml @@ -43,8 +43,9 @@ dependencies = [ "pyyaml", "typer", "uvicorn", - # local dependency - "s2gos-common>=0.0.0", + # Eozilla dependencies + "gavicore", + "wraptile", ] [project.scripts] @@ -74,4 +75,4 @@ include = [ [tool.hatch.build.targets.wheel] include = [ "src/s2gos_server/**/*" -] \ No newline at end of file +] diff --git a/s2gos-server/src/s2gos_server/app.py b/s2gos-server/src/s2gos_server/app.py deleted file mode 100644 index 782fcb3..0000000 --- a/s2gos-server/src/s2gos_server/app.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import logging -import time -from typing import Awaitable, Callable - -from fastapi import FastAPI, Request, Response -from fastapi.responses import JSONResponse - -from .exceptions import ServiceException - -app = FastAPI() - - -@app.exception_handler(ServiceException) -async def json_http_exception_handler( - _request: Request, exc: ServiceException -) -> JSONResponse: - return JSONResponse( - status_code=exc.status_code, - content=exc.content.model_dump( - mode="json", exclude_defaults=False, exclude_none=True, exclude_unset=True - ), - ) - - -@app.middleware("http") -async def log_request_duration( - request: Request, call_next: Callable[[Request], Awaitable[Response]] -) -> Response: - start_time = time.perf_counter() - - # Process the request - response = await call_next(request) - - # Calculate duration - duration = time.perf_counter() - start_time - - # Log info (method, URL path, duration in ms) - logger = logging.getLogger("uvicorn.request_duration") - logger.debug( - f"{request.method} {request.url.path} completed in {duration * 1000:.2f} ms" - ) - - return response diff --git a/s2gos-server/src/s2gos_server/constants.py b/s2gos-server/src/s2gos_server/constants.py deleted file mode 100644 index 644f3d9..0000000 --- a/s2gos-server/src/s2gos_server/constants.py +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Final - -ENV_VAR_SERVER_HOST = "S2GOS_SERVER_HOST" -ENV_VAR_SERVER_PORT = "S2GOS_SERVER_PORT" -ENV_VAR_SERVICE: Final = "S2GOS_SERVICE" - -DEFAULT_HOST = "127.0.0.1" -DEFAULT_PORT = 8008 diff --git a/s2gos-server/src/s2gos_server/exceptions.py b/s2gos-server/src/s2gos_server/exceptions.py deleted file mode 100644 index c2fbb0f..0000000 --- a/s2gos-server/src/s2gos_server/exceptions.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import traceback -from http import HTTPStatus -from typing import Optional - -from fastapi import HTTPException - -from s2gos_common.models import ApiError - - -class ServiceException(HTTPException): - """Raised if a service error occurred.""" - - def __init__( - self, - status_code: int, - detail: str, - exception: Optional[Exception] = None, - ): - super().__init__(status_code=status_code, detail=detail) - self.content = ApiError( - type=type(exception).__name__ if exception is not None else "ApiError", - status=status_code, - title=HTTPStatus(status_code).phrase, - detail=detail, - traceback=( - traceback.format_exception( - type(exception), exception, exception.__traceback__ - ) - if exception is not None - else None - ), - ) - - -class ServiceConfigException(ServiceException): - """Raised if a service configuration error occurred.""" - - def __init__(self, message: str): - super().__init__(status_code=500, detail=message, exception=self) diff --git a/s2gos-server/src/s2gos_server/logging.py b/s2gos-server/src/s2gos_server/logging.py deleted file mode 100644 index 7da0322..0000000 --- a/s2gos-server/src/s2gos_server/logging.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import logging - - -class LogMessageFilter(logging.Filter): - def __init__(self, *excludes: str): - super().__init__(f"Log message filter: {excludes}") - self.excludes = excludes - - def filter(self, record: logging.LogRecord) -> bool: - if record.name == "uvicorn.access": - for exclude in self.excludes: - if exclude in record.getMessage(): - return False - return True diff --git a/s2gos-server/src/s2gos_server/main.py b/s2gos-server/src/s2gos_server/main.py deleted file mode 100644 index 83d924e..0000000 --- a/s2gos-server/src/s2gos_server/main.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from . import routes -from .app import app - -""" -This module imports both, the FastAPI `app` instance and the application's -path functions from the `routes` module. -It also sets the server's service instance and exports the application as -the `app` module attribute. -""" - -__all__ = ["app", "routes"] diff --git a/s2gos-server/src/s2gos_server/provider.py b/s2gos-server/src/s2gos_server/provider.py deleted file mode 100644 index f29141c..0000000 --- a/s2gos-server/src/s2gos_server/provider.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import logging - -from s2gos_common.service import Service - -from .services.base import ServiceBase - - -def get_service() -> Service: - return ServiceProvider.get_instance() - - -class ServiceProvider: - _service: Service | None = None - - @classmethod - def get_instance(cls) -> Service: - if cls._service is None: - cls.set_instance(ServiceBase.load()) - assert cls._service is not None - return cls._service - - @classmethod - def set_instance(cls, service: Service): - cls._service = service - logger = logging.getLogger("uvicorn") - logger.info(f"Using service instance of type {type(service).__name__}") diff --git a/s2gos-server/src/s2gos_server/routes.py b/s2gos-server/src/s2gos_server/routes.py deleted file mode 100644 index 4f8dc2f..0000000 --- a/s2gos-server/src/s2gos_server/routes.py +++ /dev/null @@ -1,118 +0,0 @@ -# generated by gen_server.py: -# filename: routes.py: -# timestamp: 2025-10-01T16:12:51.474920 - -import fastapi - -from s2gos_common.models import ( - ProcessRequest, -) -from s2gos_common.service import Service - -from .app import app -from .provider import get_service - - -# noinspection PyPep8Naming -@app.get("/") -async def get_capabilities( - request: fastapi.Request, - response: fastapi.Response, - service: Service = fastapi.Depends(get_service), -): - return await service.get_capabilities(request=request, response=response) - - -# noinspection PyPep8Naming -@app.get("/conformance") -async def get_conformance( - request: fastapi.Request, - response: fastapi.Response, - service: Service = fastapi.Depends(get_service), -): - return await service.get_conformance(request=request, response=response) - - -# noinspection PyPep8Naming -@app.get("/processes") -async def get_processes( - request: fastapi.Request, - response: fastapi.Response, - service: Service = fastapi.Depends(get_service), -): - return await service.get_processes(request=request, response=response) - - -# noinspection PyPep8Naming -@app.get("/processes/{processID}") -async def get_process( - processID: str, - request: fastapi.Request, - response: fastapi.Response, - service: Service = fastapi.Depends(get_service), -): - return await service.get_process( - process_id=processID, request=request, response=response - ) - - -# noinspection PyPep8Naming -@app.post("/processes/{processID}/execution", status_code=201) -async def execute_process( - processID: str, - process_request: ProcessRequest, - request: fastapi.Request, - response: fastapi.Response, - service: Service = fastapi.Depends(get_service), -): - return await service.execute_process( - process_id=processID, - process_request=process_request, - request=request, - response=response, - ) - - -# noinspection PyPep8Naming -@app.get("/jobs") -async def get_jobs( - request: fastapi.Request, - response: fastapi.Response, - service: Service = fastapi.Depends(get_service), -): - return await service.get_jobs(request=request, response=response) - - -# noinspection PyPep8Naming -@app.get("/jobs/{jobId}") -async def get_job( - jobId: str, - request: fastapi.Request, - response: fastapi.Response, - service: Service = fastapi.Depends(get_service), -): - return await service.get_job(job_id=jobId, request=request, response=response) - - -# noinspection PyPep8Naming -@app.delete("/jobs/{jobId}") -async def dismiss_job( - jobId: str, - request: fastapi.Request, - response: fastapi.Response, - service: Service = fastapi.Depends(get_service), -): - return await service.dismiss_job(job_id=jobId, request=request, response=response) - - -# noinspection PyPep8Naming -@app.get("/jobs/{jobId}/results") -async def get_job_results( - jobId: str, - request: fastapi.Request, - response: fastapi.Response, - service: Service = fastapi.Depends(get_service), -): - return await service.get_job_results( - job_id=jobId, request=request, response=response - ) diff --git a/s2gos-server/src/s2gos_server/services/__init__.py b/s2gos-server/src/s2gos_server/services/__init__.py deleted file mode 100644 index 22d05e1..0000000 --- a/s2gos-server/src/s2gos_server/services/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. diff --git a/s2gos-server/src/s2gos_server/services/airflow/__init__.py b/s2gos-server/src/s2gos_server/services/airflow/__init__.py deleted file mode 100644 index dab9b05..0000000 --- a/s2gos-server/src/s2gos_server/services/airflow/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from .airflow_service import DEFAULT_AIRFLOW_BASE_URL, AirflowService - -service = AirflowService( - title="Airflow Service", - description=( - "A gateway API compliant with OGC API - Processes that uses an Airflow backend." - ), -) - -__all__ = [ - "DEFAULT_AIRFLOW_BASE_URL", - "AirflowService", - "service", -] diff --git a/s2gos-server/src/s2gos_server/services/airflow/airflow_service.py b/s2gos-server/src/s2gos_server/services/airflow/airflow_service.py deleted file mode 100644 index 31be695..0000000 --- a/s2gos-server/src/s2gos_server/services/airflow/airflow_service.py +++ /dev/null @@ -1,298 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import datetime -import os -from functools import cached_property -from typing import Any, Optional - -import fastapi -import requests -from airflow_client.client import ( - ApiClient, - ApiException, - Configuration, - DAGRunPatchBody, - DAGRunPatchStates, - DAGRunResponse, - DagRunState, - TriggerDAGRunPostBody, -) -from airflow_client.client.api import DAGApi -from airflow_client.client.api import DagRunApi as DAGRunApi -from airflow_client.client.api import XComApi - -from s2gos_common.models import ( - InputDescription, - JobInfo, - JobList, - JobResults, - JobStatus, - JobType, - OutputDescription, - ProcessDescription, - ProcessList, - ProcessRequest, - ProcessSummary, -) -from s2gos_server.exceptions import ServiceException -from s2gos_server.services.base import ServiceBase - -DEFAULT_AIRFLOW_BASE_URL = "http://localhost:8080" - - -class AirflowService(ServiceBase): - def __init__( - self, - title: str, - description: Optional[str] = None, - ): - super().__init__(title=title, description=description) - self._exec_count: int = 0 - self._airflow_base_url: Optional[str] = None - self._airflow_username: Optional[str] = None - self._airflow_password: Optional[str] = None - - def configure( - self, - airflow_base_url: Optional[str] = None, - airflow_username: Optional[str] = None, - airflow_password: Optional[str] = None, - ): - """ - Configure the Airflow service. - - Args: - airflow_base_url: The base URL of the Airflow web API, defaults to - `http://localhost:8080`. - airflow_username: The Airflow username, defaults to `admin`. - airflow_password: The Airflow password. - For an Airflow installation with the simple Auth manager, - use the one from - `.airflow/simple_auth_manager_passwords.json.generated`. - """ - self._airflow_base_url = airflow_base_url - self._airflow_username = airflow_username - self._airflow_password = airflow_password - - async def get_processes( - self, request: fastapi.Request, *args, **kwargs - ) -> ProcessList: - processes: list[ProcessSummary] = [] - try: - dag_collection = self.airflow_dag_api.get_dags( - exclude_stale=True, - limit=None, - owners=None, # TODO important, get for current user only - ) - except ApiException as e: - raise ServiceException(e.status, detail=e.reason, exception=e) from e - if dag_collection and dag_collection.dags: - for dag in dag_collection.dags: - # https://github.com/apache/airflow-client-python/blob/main/airflow_client/client/models/dag_response.py - processes.append( - ProcessSummary( - id=dag.dag_id, - version="0.0.0", # TODO: get version - title=dag.dag_display_name, - description=dag.description, - ) - ) - return ProcessList( - processes=processes, - links=[self.get_self_link(request, "get_processes")], - ) - - async def get_process(self, process_id: str, *args, **kwargs) -> ProcessDescription: - try: - dag_details = self.airflow_dag_api.get_dag_details(dag_id=process_id) - except ApiException as e: - raise ServiceException(e.status, detail=e.reason, exception=e) from e - - inputs: dict[str, InputDescription] = {} - if dag_details.params: - # TODO: check that 'param_value' will be an instance of 'Param' model - for param_key, param_value in dag_details.params.items(): - # TODO: inputs[param_key] = InputDescription(param_value. ...) - print(f" - {param_key} = {param_value} (type {type(param_value)}):") - else: - print(" No parameters (params) defined for this DAG.") - - # TODO: where to get outputs from? - outputs: dict[str, OutputDescription] = {} - - return ProcessDescription( - id=dag_details.dag_id, - version="0.0.0", # TODO: get version - title=dag_details.dag_display_name, - description=dag_details.doc_md or dag_details.description, - inputs=inputs, - outputs=outputs, - ) - - async def execute_process( - self, process_id: str, process_request: ProcessRequest, *args, **kwargs - ) -> JobInfo: - logical_date = datetime.datetime.now(datetime.timezone.utc) - dag_run_id = self.new_dag_run_id(process_id, logical_date) - dag_run_body = TriggerDAGRunPostBody( - dag_run_id=dag_run_id, - conf=process_request.inputs, - logical_date=logical_date, - ) - try: - dag_run = self.airflow_dag_run_api.trigger_dag_run(process_id, dag_run_body) - except ApiException as e: - raise ServiceException(e.status, e.reason, exception=e) from e - return self.dag_run_to_job_info(dag_run) - - async def get_jobs(self, request: fastapi.Request, *args, **kwargs) -> JobList: - try: - dag_collection = self.airflow_dag_api.get_dags( - exclude_stale=True, - limit=None, - owners=None, # TODO important, get for current user only - ) - except ApiException as e: - raise ServiceException(e.status, detail=e.reason, exception=e) from e - - jobs: list[JobInfo] = [] - for dag in dag_collection.dags: - try: - dag_run_collection = self.airflow_dag_run_api.get_dag_runs(dag.dag_id) - except ApiException as e: - raise ServiceException(e.status, e.reason, exception=e) from e - jobs.extend( - self.dag_run_to_job_info(dag_run) - for dag_run in dag_run_collection.dag_runs - ) - return JobList(jobs=jobs, links=[self.get_self_link(request, name="get_jobs")]) - - async def get_job(self, job_id: str, *args, **kwargs) -> JobInfo: - dag_id = self.get_dag_id_from_job_id(job_id) - try: - dag_run = self.airflow_dag_run_api.get_dag_run(dag_id, job_id) - except ApiException as e: - raise ServiceException(e.status, e.reason, exception=e) from e - return self.dag_run_to_job_info(dag_run) - - async def dismiss_job(self, job_id: str, *args, **kwargs) -> JobInfo: - dag_id = self.get_dag_id_from_job_id(job_id) - dag_run_patch = DAGRunPatchBody( - note="Cancelled", state=DAGRunPatchStates.FAILED - ) - try: - # TODO: check if this really works - dag_run = self.airflow_dag_run_api.patch_dag_run( - dag_id, job_id, dag_run_patch - ) - except ApiException as e: - raise ServiceException(e.status, e.reason, exception=e) from e - return self.dag_run_to_job_info(dag_run) - - async def get_job_results(self, job_id: str, *args, **kwargs) -> JobResults: - dag_id = self.get_dag_id_from_job_id(job_id) - return_value: Optional[Any] = None - try: - xcom_entry = self.airflow_xcom_api.get_xcom_entry( - dag_id=dag_id, - dag_run_id=job_id, - task_id=dag_id + "_task", - xcom_key="return_value", - ) - if xcom_entry is not None and xcom_entry.actual_instance is not None: - return_value = xcom_entry.actual_instance.value - except ApiException as e: - raise ServiceException(e.status, e.reason, exception=e) from e - # TODO: use keys from output definitions, if provided. - # Otherwise, "return_value" is correct. - return JobResults({"return_value": return_value}) # type: ignore[dict-item] - - def new_dag_run_id(self, dag_id: str, logical_time: datetime.datetime): - self._exec_count += 1 - return f"{dag_id}__{logical_time.strftime('%Y%m%d%H%M%S')}_{self._exec_count}" - - @classmethod - def get_dag_id_from_job_id(cls, job_id): - return job_id.split("__", maxsplit=1)[0] - - @classmethod - def dag_run_to_job_info(cls, dag_run: DAGRunResponse) -> JobInfo: - return JobInfo( - type=JobType.process, - processID=dag_run.dag_id, - jobID=dag_run.dag_run_id, - status=cls.dag_run_state_to_job_status(dag_run.state), - progress=None, # check, it seems we have no good option here - message=dag_run.note, # check - created=dag_run.queued_at, - started=dag_run.start_date, - updated=dag_run.last_scheduling_decision, - finished=dag_run.end_date, - ) - - @classmethod - def dag_run_state_to_job_status(cls, dag_run_state: DagRunState) -> JobStatus: - mapping = { - DagRunState.RUNNING: JobStatus.running, - DagRunState.FAILED: JobStatus.failed, - DagRunState.QUEUED: JobStatus.accepted, - DagRunState.SUCCESS: JobStatus.successful, - } - return mapping[dag_run_state] - - @cached_property - def airflow_dag_api(self) -> DAGApi: - return DAGApi(self.airflow_client) - - @cached_property - def airflow_dag_run_api(self) -> DAGRunApi: - return DAGRunApi(self.airflow_client) - - @cached_property - def airflow_xcom_api(self) -> XComApi: - return XComApi(self.airflow_client) - - @cached_property - def airflow_client(self) -> ApiClient: - airflow_base_url: str = ( - self._airflow_base_url - or os.getenv("AIRFLOW_API_BASE_URL") - or DEFAULT_AIRFLOW_BASE_URL - ) - airflow_username: str = ( - self._airflow_username or os.getenv("AIRFLOW_USERNAME") or "admin" - ) - airflow_password = self._airflow_password or os.getenv("AIRFLOW_PASSWORD") - if not airflow_password: - raise RuntimeError( - "missing Airflow password; please set env var AIRFLOW_PASSWORD" - ) - access_token = self.fetch_access_token( - airflow_base_url, - username=airflow_username, - password=airflow_password, - ) - configuration = Configuration(host=airflow_base_url, access_token=access_token) - return ApiClient(configuration) - - @classmethod - def fetch_access_token( - cls, - base_url: str, - username: Optional[str] = None, - password: Optional[str] = None, - ) -> str: - response = requests.post( - f"{base_url}/auth/token", - json={"username": username, "password": password}, - ) - try: - response.raise_for_status() - token_data = response.json() - return token_data.get("access_token") - except requests.exceptions.HTTPError as e: - raise ServiceException( - response.status_code, detail=response.reason, exception=e - ) from e diff --git a/s2gos-server/src/s2gos_server/services/base/__init__.py b/s2gos-server/src/s2gos_server/services/base/__init__.py deleted file mode 100644 index 633a35f..0000000 --- a/s2gos-server/src/s2gos_server/services/base/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from .service_base import DEFAULT_CONFORMS_TO, ServiceBase - -__all__ = [ - "DEFAULT_CONFORMS_TO", - "ServiceBase", -] diff --git a/s2gos-server/src/s2gos_server/services/base/service_base.py b/s2gos-server/src/s2gos_server/services/base/service_base.py deleted file mode 100644 index d863a05..0000000 --- a/s2gos-server/src/s2gos_server/services/base/service_base.py +++ /dev/null @@ -1,168 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import logging -import os -import shlex -from abc import ABC -from typing import Optional - -import fastapi -import yaml -from starlette.routing import Route - -from s2gos_common.models import ( - Capabilities, - ConformanceDeclaration, - Link, -) -from s2gos_common.service import Service -from s2gos_common.util.dynimp import import_value -from s2gos_server.constants import ENV_VAR_SERVICE -from s2gos_server.exceptions import ServiceConfigException - -DEFAULT_CONFORMS_TO = [ - "http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/core", - "http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/ogc-process-description", - "http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/json", - # "http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/html", - "http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/oas30", - "http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/job-list", - # "http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/callback", - "http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/dismiss", -] - - -class ServiceBase(Service, ABC): - @classmethod - def load(cls) -> "ServiceBase": - """ - Load the service instance from environment variable. - - Returns: - A configured service instance of type `ServiceBase`. - - Raises: - ConfigException: if a server configuration error occurs. - """ - service_spec: str | None = os.environ.get(ENV_VAR_SERVICE) - service_args = shlex.split(service_spec) if service_spec else [] - args = [] - kwargs = {} - for a in service_args: - if a.startswith("-"): - if not a.startswith("--"): - kv_example = "--key[=value]" - raise ServiceConfigException( - f"Service options must have the form {kv_example!r}, " - f"but got {a!r}." - ) - kv = [p.strip() for p in a[2:].split("=", maxsplit=1)] - k = kv[0] - k = k.replace("-", "_") - maybe_invert = k.startswith("no_") and len(k) > 3 - if not k.isidentifier(): - kv_example = "--key[=value]" - raise ServiceConfigException( - f"Service options must have the form {kv_example!r}, " - f"but got {kv[0]!r} as key, which is not an identifier." - ) - v = yaml.safe_load(kv[1]) if len(kv) == 2 else True - if maybe_invert and isinstance(v, bool): - kwargs[k[3:]] = not v - else: - kwargs[k] = v - else: - args.append(a) - - if not args: - service_help = ( - f"The service must be passed in the form {'path.to.module:service'!r} " - "either as first command-line argument or using the environment " - f"variable {ENV_VAR_SERVICE!r}." - ) - raise ServiceConfigException(f"Service not specified. {service_help}") - - service_ref, args = args[0], args[1:] - try: - service = import_value( - service_ref, - type=ServiceBase, # type: ignore[type-abstract] - name="service", - example="path.to.module:service", - ) - except (ValueError, TypeError) as e: - raise ServiceConfigException(f"{e}") - logger = logging.getLogger("uvicorn") - logger.info(f"Created service instance of type {type(service).__name__}") - service.configure(*args, **kwargs) - return service - - def __init__( - self, - title: str, - description: Optional[str] = None, - conforms_to: Optional[list[str]] = None, - ): - self.title = title - self.description = description - self.conforms_to = conforms_to or DEFAULT_CONFORMS_TO - self.logger = logging.getLogger("uvicorn") - - # noinspection PyMethodMayBeStatic - def configure(self, *args, **kwargs): - """Configure this service by the given positional and keyword arguments. - - The default implementation does nothing. - - Args: - args: positional arguments. - kwargs: keyword arguments. - - Raises: - ConfigException: if a server configuration error occurs. - """ - - async def get_capabilities( - self, request: fastapi.Request, **kwargs - ) -> Capabilities: - app: fastapi.FastAPI = request.app - links = [self.get_self_link(request, "get_capabilities")] + [ - Link( - href=self.get_url(request, r.path), - title=r.name, - rel="service", - type=self.get_link_type(r.name), - hreflang="en", - ) - for r in app.routes - if isinstance(r, Route) - ] - return Capabilities( - title=self.title, - description=self.description, - links=links, - ) - - async def get_conformance(self, **_kwargs) -> ConformanceDeclaration: - return ConformanceDeclaration(conformsTo=self.conforms_to) - - @classmethod - def get_self_link(cls, request: fastapi.Request, name: str, **path_params) -> Link: - return Link( - href=str(request.url_for(name, **path_params)), - rel="self", - title=name, - type=cls.get_link_type(name), - hreflang="en", - ) - - @classmethod - def get_link_type(cls, name: str) -> str: - html_names = ("swagger_ui_html", "swagger_ui_redirect", "redoc_html") - return "text/html" if name in html_names else "application/json" - - @classmethod - def get_url(cls, request: fastapi.Request, path: str): - return str(request.base_url.replace(path=path)) diff --git a/s2gos-server/src/s2gos_server/services/local/__init__.py b/s2gos-server/src/s2gos_server/services/local/__init__.py deleted file mode 100644 index 6619deb..0000000 --- a/s2gos-server/src/s2gos_server/services/local/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from s2gos_common.process.job import ( - Job, - JobCancelledException, - JobContext, -) - -from .local_service import LocalService - -__all__ = [ - "LocalService", - "Job", - "JobCancelledException", - "JobContext", -] diff --git a/s2gos-server/src/s2gos_server/services/local/local_service.py b/s2gos-server/src/s2gos_server/services/local/local_service.py deleted file mode 100644 index 78e1d68..0000000 --- a/s2gos-server/src/s2gos_server/services/local/local_service.py +++ /dev/null @@ -1,173 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from concurrent.futures import ThreadPoolExecutor -from concurrent.futures.process import ProcessPoolExecutor -from typing import Callable, Optional - -import fastapi -import pydantic - -from s2gos_common.models import ( - JobInfo, - JobList, - JobResults, - JobStatus, - ProcessDescription, - ProcessList, - ProcessRequest, - ProcessSummary, -) -from s2gos_common.process import Job, Process, ProcessRegistry -from s2gos_server.exceptions import ServiceException -from s2gos_server.services.base import ServiceBase - - -class LocalService(ServiceBase): - def __init__( - self, - title: str, - description: Optional[str] = None, - process_registry: Optional[ProcessRegistry] = None, - ): - super().__init__(title=title, description=description) - self.executor: Optional[ThreadPoolExecutor | ProcessPoolExecutor] = None - self.process_registry = process_registry or ProcessRegistry() - self.jobs: dict[str, Job] = {} - - def configure( - self, processes: Optional[bool] = None, max_workers: Optional[int] = None - ): - """ - Configure the local service. - - Args: - processes: Whether to use processes instead of threads. Defaults to threads. - max_workers: The maximum number of processes or threads. Defaults to 3. - """ - num_workers: int = max_workers or 3 - if processes: - self.executor = ProcessPoolExecutor(max_workers=num_workers) - self.logger.info(f"Using processes with max {num_workers} workers.") - else: - self.executor = ThreadPoolExecutor(max_workers=num_workers) - self.logger.info(f"Using threads with max {num_workers} workers.") - - async def get_processes(self, request: fastapi.Request, **_kwargs) -> ProcessList: - return ProcessList( - processes=[ - ProcessSummary( - **p.description.model_dump( - mode="python", - exclude={"inputs", "outputs"}, - ) - ) - for p in self.process_registry.values() - ], - links=[self.get_self_link(request, "get_processes")], - ) - - async def get_process(self, process_id: str, **kwargs) -> ProcessDescription: - process = self._get_process(process_id) - return process.description - - async def execute_process( - self, process_id: str, process_request: ProcessRequest, **_kwargs - ) -> JobInfo: - process = self._get_process(process_id) - job_id = f"job_{len(self.jobs)}" - try: - job = Job.create(process, process_request, job_id=job_id) - except pydantic.ValidationError as e: - raise ServiceException( - 400, - detail=f"Invalid parameterization for process {process_id!r}: {e}", - exception=e, - ) - self.jobs[job_id] = job - assert self.executor is not None, "illegal state: no executor specified" - job.future = self.executor.submit(job.run) - return job.job_info - - async def get_jobs(self, request: fastapi.Request, **_kwargs) -> JobList: - return JobList( - jobs=[job.job_info for job in self.jobs.values()], - links=[self.get_self_link(request, "get_jobs")], - ) - - async def get_job(self, job_id: str, *args, **kwargs) -> JobInfo: - job = self._get_job(job_id, forbidden_status_codes={}) - return job.job_info - - async def dismiss_job(self, job_id: str, *args, **_kwargs) -> JobInfo: - job = self._get_job(job_id, forbidden_status_codes={}) - if job.job_info.status in (JobStatus.accepted, JobStatus.running): - job.cancel() - elif job.job_info.status in ( - JobStatus.dismissed, - JobStatus.successful, - JobStatus.failed, - ): - del self.jobs[job_id] - return job.job_info - - async def get_job_results(self, job_id: str, *args, **_kwargs) -> JobResults: - job = self._get_job( - job_id, - forbidden_status_codes={ - JobStatus.accepted: "has not started yet", - JobStatus.running: "is still running", - JobStatus.dismissed: "has been cancelled", - JobStatus.failed: "has failed", - }, - ) - assert job.job_info.status == JobStatus.successful - assert job.future is not None - return job.future.result() - - # noinspection PyShadowingBuiltins - def process( - self, - function: Optional[Callable] = None, - /, - *, - id: Optional[str] = None, - version: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - input_fields: Optional[dict[str, pydantic.fields.FieldInfo]] = None, - output_fields: Optional[dict[str, pydantic.fields.FieldInfo]] = None, - ) -> Callable[[Callable], Callable]: - """ - A decorator that can be applied to a user function in order to - register it as a process in this registry. - - The decorator can be used with or without parameters. - """ - return self.process_registry.process( - function, - id=id, - version=version, - title=title, - description=description, - input_fields=input_fields, - output_fields=output_fields, - ) - - def _get_process(self, process_id: str) -> Process: - process = self.process_registry.get(process_id) - if process is None: - raise ServiceException(404, detail=f"Process {process_id!r} does not exist") - return process - - def _get_job( - self, job_id: str, forbidden_status_codes: dict[JobStatus, str] - ) -> Job: - job = self.jobs.get(job_id) - if job is None: - raise ServiceException(404, detail=f"Job {job_id!r} does not exist") - message = forbidden_status_codes.get(job.job_info.status) - if message: - raise ServiceException(403, detail=f"Job {job_id!r} {message}") - return job diff --git a/s2gos-server/src/s2gos_server/services/local/testing.py b/s2gos-server/src/s2gos_server/services/local/testing.py deleted file mode 100644 index 7dfffe6..0000000 --- a/s2gos-server/src/s2gos_server/services/local/testing.py +++ /dev/null @@ -1,218 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import datetime -import time -from pathlib import Path -from typing import Optional - -import pydantic -from pydantic import Field - -from s2gos_common.models import Link -from s2gos_common.process import JobContext -from s2gos_server.services.local import LocalService - -service = LocalService( - title="S2GOS API Server (local dummy for testing)", - description="Local test server implementing the OGC API - Processes 1.0 Standard", -) - - -@service.process( - id="sleep_a_while", - title="Sleep Processor", - description=( - "Sleeps for `duration` seconds. " - "Fails on purpose if `fail` is `True`. " - "Returns the effective amount of sleep in seconds." - ), -) -def sleep_a_while( - duration: float = 10.0, - fail: bool = False, -) -> float: - ctx = JobContext.get() - - t0 = time.time() - for i in range(101): - ctx.report_progress(progress=i) - if fail and i == 50: - raise RuntimeError("Woke up too early") - time.sleep(duration / 100) - return time.time() - t0 - - -@service.process( - id="primes_between", - title="Prime Processor", - description=( - "Returns the list of prime numbers between a `min_val` and `max_val`." - ), -) -def primes_between( - min_val: int = pydantic.Field(0, ge=0), - max_val: int = pydantic.Field(100, le=100), -) -> list[int]: - ctx = JobContext.get() - - if max_val < 2 or max_val <= min_val: - raise ValueError("max_val must be greater 1 and greater min_val") - - ctx.report_progress(message="Step 1: Generate sieve up to sqrt(max_val)") - limit = int(max_val**0.5) + 1 - is_prime_small = [True] * (limit + 1) - is_prime_small[0:2] = [False, False] - for i in range(2, int(limit**0.5) + 1): - if is_prime_small[i]: - for j in range(i * i, limit + 1, i): - is_prime_small[j] = False - small_primes = [i for i, prime in enumerate(is_prime_small) if prime] - - ctx.report_progress( - message="Step 2: Create the sieve for the range [min_val, max_val]" - ) - sieve_range = max_val - min_val + 1 - is_prime = [True] * sieve_range - - for p in small_primes: - # Find the first multiple of p in the range [min_val, max_val] - start = max(p * p, ((min_val + p - 1) // p) * p) - for j in range(start, max_val + 1, p): - is_prime[j - min_val] = False - - for n in range(min_val, min(min_val + 2, max_val + 1)): - if n < 2: - is_prime[n - min_val] = False - - ctx.report_progress(message="Done") - return [min_val + i for i, prime in enumerate(is_prime) if prime] - - -@service.process( - id="simulate_scene", - title="Generate scene for testing", - description=( - "Simulate a set scene images slices for testing. " - "Creates an xarray dataset with `periodicity` time slices " - "and writes it as Zarr into a temporary location. " - "Requires installed `dask`, `xarray`, and `zarr` packages." - ), - input_fields={ - "var_names": Field( - title="Variable names", - description="Comma-separated list of variable names.", - ), - "bbox": Field( - title="Bounding box", - description="Bounding box in geographical coordinates.", - json_schema_extra=dict(format="bbox"), - ), - "resolution": Field( - title="Spatial resolution", - description="Spatial resolution in degree.", - ge=0.01, - le=1.0, - ), - "start_date": Field( - title="Start date", - json_schema_extra=dict(format="date"), - ), - "end_date": Field( - title="End date", - json_schema_extra=dict(format="date"), - ), - "periodicity": Field( - title="Periodicity", - description="Size of time steps in days.", - ge=1, - le=10, - ), - "output_path": Field( - title="Output path", - description="Local output path or URI.", - ), - }, -) -def simulate_scene( - var_names: str = "a, b, c", - bbox: tuple[float, float, float, float] = (-180, -90, 180, 90), - resolution: float = 0.5, - start_date: str = "2025-01-01", - end_date: str = "2025-02-01", - periodicity: int = 1, - output_path: Optional[str] = None, -) -> Link: - # dependencies only required for this operation - import dask.array as da - import numpy as np - import xarray as xr - - # print( - # dict( - # var_names=var_names, - # bbox=bbox, - # resolution=resolution, - # start_date=start_date, - # end_date=end_date, - # periodicity=periodicity, - # ) - # ) - - var_names_: list[str] = [name.strip() for name in var_names.split(",")] - start_date_: datetime.date = datetime.date.fromisoformat(start_date) - end_date_: datetime.date = datetime.date.fromisoformat(end_date) - - x1, y1, x2, y2 = bbox - x_size = round((x2 - x1) / resolution) - y_size = round((y2 - y1) / resolution) - time_size = round((end_date_ - start_date_).days / periodicity) - r05 = resolution / 2 - - dataset = xr.Dataset() - dataset.coords["lon"] = xr.DataArray( - np.linspace(x1 + r05, x2 - r05, x_size), dims="lon" - ) - dataset.coords["lat"] = xr.DataArray( - np.linspace(y1 + r05, y2 - r05, y_size), dims="lat" - ) - dataset.coords["time"] = xr.DataArray( - np.array( - [start_date_ + datetime.timedelta(days=days) for days in range(time_size)], - dtype=np.datetime64, - ), - dims="time", - ) - for var_name in var_names_: - dataset[var_name] = xr.DataArray( - da.zeros(shape=(time_size, y_size, x_size)), dims=("time", "lat", "lon") - ) - - if not output_path: - output_path = "memory://datacube.zarr" - - dataset.to_zarr(output_path, mode="w", zarr_format=3) - if "://" in output_path: - href = output_path - else: - href = Path(output_path).resolve().as_uri() - # noinspection PyArgumentList - return Link(href=href, hreflang=None, type="application/zarr", rel=None) - - -class SceneSpec(pydantic.BaseModel): - threshold: float - factor: float - # TODO: uncomment and see tests fail! - # bbox: Optional[Bbox] = None - - -@service.process( - id="return_base_model", - title="BaseModel Test", -) -def return_base_model( - scene_spec: SceneSpec, -) -> SceneSpec: - return scene_spec diff --git a/s2gos-server/src/tests/services/__init__.py b/s2gos-server/src/tests/services/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-server/src/tests/services/airflow/__init__.py b/s2gos-server/src/tests/services/airflow/__init__.py deleted file mode 100644 index 22d05e1..0000000 --- a/s2gos-server/src/tests/services/airflow/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. diff --git a/s2gos-server/src/tests/services/airflow/test_airflow_service.py b/s2gos-server/src/tests/services/airflow/test_airflow_service.py deleted file mode 100644 index e1604ea..0000000 --- a/s2gos-server/src/tests/services/airflow/test_airflow_service.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import unittest -import warnings -from unittest import IsolatedAsyncioTestCase - -import fastapi -import requests - -from s2gos_common.models import ( - Capabilities, - ConformanceDeclaration, - ProcessDescription, - ProcessList, -) -from s2gos_common.util.testing import set_env -from s2gos_server.main import app -from s2gos_server.provider import ServiceProvider, get_service -from s2gos_server.services.airflow import DEFAULT_AIRFLOW_BASE_URL, AirflowService - - -def is_airflow_running(url: str, timeout: float = 1.0) -> bool: - try: - requests.head(url, allow_redirects=True, timeout=timeout) - return True - except requests.RequestException: - return False - - -@unittest.skipUnless( - is_airflow_running(DEFAULT_AIRFLOW_BASE_URL), - reason=f"No Airflow server running on {DEFAULT_AIRFLOW_BASE_URL}", -) -class AirflowServiceTest(IsolatedAsyncioTestCase): - async def asyncSetUp(self): - self.app = app - self.restore_env = set_env( - S2GOS_SERVICE="s2gos_server.services.airflow:service", - ) - ServiceProvider._service = None - self.service = get_service() - self.assertIsInstance(self.service, AirflowService) - self.service.configure() - - async def asyncTearDown(self): - self.restore_env() - # comment out to check generated DAGs - # shutil.rmtree(S2GOS_AIRFLOW_DAGS_FOLDER, ignore_errors=True) - - def get_request(self) -> fastapi.Request: - return fastapi.Request({"type": "http", "app": self.app, "headers": {}}) - - async def test_get_capabilities(self): - caps = await self.service.get_capabilities(request=self.get_request()) - self.assertIsInstance(caps, Capabilities) - - async def test_get_conformance(self): - conf = await self.service.get_conformance(request=self.get_request()) - self.assertIsInstance(conf, ConformanceDeclaration) - - async def test_get_processes(self): - processes = await self.service.get_processes(request=self.get_request()) - self.assertIsInstance(processes, ProcessList) - - async def test_get_process(self): - process_list = await self.service.get_processes(request=self.get_request()) - processes = process_list.processes - if not processes: - warnings.warn("Skipping test; no Airflow processes found") - return - - process = await self.service.get_process( - process_id=processes[0].id, request=self.get_request() - ) - self.assertIsInstance(process, ProcessDescription) diff --git a/s2gos-server/src/tests/services/base/__init__.py b/s2gos-server/src/tests/services/base/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-server/src/tests/services/base/test_service_base.py b/s2gos-server/src/tests/services/base/test_service_base.py deleted file mode 100644 index 0b54ff9..0000000 --- a/s2gos-server/src/tests/services/base/test_service_base.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Optional -from unittest import TestCase - -import pytest - -from s2gos_common.models import ( - JobInfo, - JobList, - JobResults, - ProcessDescription, - ProcessList, - ProcessRequest, -) -from s2gos_common.util.testing import set_env_cm -from s2gos_server.constants import ENV_VAR_SERVICE -from s2gos_server.exceptions import ServiceConfigException -from s2gos_server.services.base import ServiceBase - - -class MyService(ServiceBase): - def __init__(self): - super().__init__("Test Service") - self.threads: Optional[bool] = None - self.workers: Optional[int] = None - - def configure(self, threads: Optional[bool] = None, workers: Optional[int] = None): - self.threads = threads - self.workers = workers - - async def get_processes(self, *args, **kwargs) -> ProcessList: - raise NotImplementedError - - async def get_process(self, process_id: str, *args, **kwargs) -> ProcessDescription: - raise NotImplementedError - - async def execute_process( - self, process_id: str, process_request: ProcessRequest, *args, **kwargs - ) -> JobInfo: - raise NotImplementedError - - async def get_jobs(self, *args, **kwargs) -> JobList: - raise NotImplementedError - - async def get_job(self, job_id: str, *args, **kwargs) -> JobInfo: - raise NotImplementedError - - async def dismiss_job(self, job_id: str, *args, **kwargs) -> JobInfo: - raise NotImplementedError - - async def get_job_results(self, job_id: str, *args, **kwargs) -> JobResults: - raise NotImplementedError - - -service = MyService() - - -class ServiceBaseTest(TestCase): - def test_load_without_options(self): - service_spec = "tests.services.base.test_service_base:service" - with set_env_cm(**{ENV_VAR_SERVICE: service_spec}): - s = ServiceBase.load() - self.assertIsInstance(s, MyService) - self.assertEqual(None, s.threads) - self.assertEqual(None, s.workers) - - def test_load_with_options(self): - service_spec = ( - "tests.services.base.test_service_base:service --threads --workers=4" - ) - with set_env_cm(**{ENV_VAR_SERVICE: service_spec}): - s = ServiceBase.load() - self.assertIsInstance(s, MyService) - self.assertEqual(True, s.threads) - self.assertEqual(4, s.workers) - - def test_load_with_no_option(self): - service_spec = ( - "tests.services.base.test_service_base:service --no-threads --workers=2" - ) - with set_env_cm(**{ENV_VAR_SERVICE: service_spec}): - s = ServiceBase.load() - self.assertIsInstance(s, MyService) - self.assertEqual(False, s.threads) - self.assertEqual(2, s.workers) - - def test_load_env_var_not_set(self): - self.assert_fails_with_config_exception( - None, r"Service not specified\. The service must be passed in the form" - ) - - def test_load_env_var_empty(self): - self.assert_fails_with_config_exception( - "", r"Service not specified\. The service must be passed in the form" - ) - - def test_load_env_var_with_invalid_service_spec(self): - self.assert_fails_with_config_exception( - "hello.service", - r"The service reference must be passed in the form " - r"'path\.to\.module\:service', but got 'hello\.service'\.", - ) - - def test_load_env_var_with_invalid_service_module(self): - self.assert_fails_with_config_exception( - "hel.lo:service", - r"Cannot import module 'hel.lo'\.", - ) - - def test_load_env_var_with_invalid_service_attrib(self): - self.assert_fails_with_config_exception( - "tests.services.base.test_service_base:servize", - r"Module 'tests\.services\.base\.test_service_base' " - r"has no attribute 'servize'\.", - ) - - def test_load_env_var_with_invalid_service_type(self): - self.assert_fails_with_config_exception( - "tests.services.base.test_service_base:MyService", - r"The reference 'tests\.services\.base\.test_service_base:MyService' " - r"should refer to a service of type ServiceBase, but got type ABCMeta\.", - ) - - def test_load_env_var_with_invalid_opt(self): - self.assert_fails_with_config_exception( - "module:attr -pippo", - r"Service options must have the form '\-\-key\[=value\]', " - r"but got '-pippo'\.", - ) - - def test_load_env_var_with_invalid_opt_ident(self): - self.assert_fails_with_config_exception( - "module:attr --12=13", - r"Service options must have the form '--key\[=value\]', " - r"but got '12' as key, which is not an identifier\.", - ) - - # noinspection PyMethodMayBeStatic - def assert_fails_with_config_exception(self, value: str | None, match: str): - with set_env_cm(**{ENV_VAR_SERVICE: value}): - with pytest.raises(ServiceConfigException, match=match): - ServiceBase.load() diff --git a/s2gos-server/src/tests/services/local/__init__.py b/s2gos-server/src/tests/services/local/__init__.py deleted file mode 100644 index 22d05e1..0000000 --- a/s2gos-server/src/tests/services/local/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. diff --git a/s2gos-server/src/tests/services/local/test_local_service.py b/s2gos-server/src/tests/services/local/test_local_service.py deleted file mode 100644 index 5cd0643..0000000 --- a/s2gos-server/src/tests/services/local/test_local_service.py +++ /dev/null @@ -1,179 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from concurrent.futures.process import ProcessPoolExecutor -from concurrent.futures.thread import ThreadPoolExecutor -from unittest import IsolatedAsyncioTestCase, TestCase - -import fastapi -import pytest - -from s2gos_common.models import ( - Capabilities, - ConformanceDeclaration, - JobInfo, - JobList, - JobResults, - JobStatus, - ProcessDescription, - ProcessList, - ProcessRequest, -) -from s2gos_common.process import Process -from s2gos_common.util.testing import set_env -from s2gos_server.exceptions import ServiceException -from s2gos_server.main import app -from s2gos_server.provider import ServiceProvider, get_service -from s2gos_server.services.local import LocalService - - -class LocalServiceSetupTest(TestCase): - def setUp(self): - service = LocalService(title="OGC API - Processes - Test Service") - - @service.process(id="foo", version="1.0.1") - def foo(x: bool, y: int) -> float: - return 2 * y if x else y / 2 - - @service.process(id="bar", version="1.4.2") - def bar(x: bool, y: int) -> float: - return 2 * y if x else y / 2 - - self.service = service - - def test_configure(self): - self.service.configure(processes=False, max_workers=1) - self.assertIsInstance(self.service.executor, ThreadPoolExecutor) - self.service.configure(processes=True, max_workers=4) - self.assertIsInstance(self.service.executor, ProcessPoolExecutor) - - def test_server_setup_ok(self): - service = self.service - - foo_entry = service.process_registry.get("foo") - self.assertIsInstance(foo_entry, Process) - self.assertTrue(callable(foo_entry.function)) - foo_process = foo_entry.description - self.assertIsInstance(foo_process, ProcessDescription) - self.assertEqual("foo", foo_process.id) - self.assertEqual("1.0.1", foo_process.version) - - bar_entry = service.process_registry.get("bar") - self.assertIsInstance(bar_entry, Process) - self.assertTrue(callable(bar_entry.function)) - bar_process = bar_entry.description - self.assertIsInstance(bar_process, ProcessDescription) - self.assertEqual("bar", bar_process.id) - self.assertEqual("1.4.2", bar_process.version) - - -class LocalServiceTest(IsolatedAsyncioTestCase): - async def asyncSetUp(self): - self.app = app - self.restore_env = set_env( - S2GOS_SERVICE="s2gos_server.services.local.testing:service" - ) - ServiceProvider._service = None - self.service = get_service() - self.assertIsInstance(self.service, LocalService) - - async def asyncTearDown(self): - self.restore_env() - - def get_request(self) -> fastapi.Request: - return fastapi.Request({"type": "http", "app": self.app, "headers": {}}) - - async def test_get_capabilities(self): - caps = await self.service.get_capabilities(request=self.get_request()) - self.assertIsInstance(caps, Capabilities) - - async def test_get_conformance(self): - conf = await self.service.get_conformance(request=self.get_request()) - self.assertIsInstance(conf, ConformanceDeclaration) - - async def test_get_processes(self): - processes = await self.service.get_processes(request=self.get_request()) - self.assertIsInstance(processes, ProcessList) - - async def test_get_process(self): - process = await self.service.get_process( - process_id="primes_between", request=self.get_request() - ) - self.assertIsInstance(process, ProcessDescription) - - async def test_execute_process(self): - job_info = await self.service.execute_process( - process_id="primes_between", - process_request=ProcessRequest(inputs=dict(min_val=10, max_val=30)), - request=self.get_request(), - ) - self.assertIsInstance(job_info, JobInfo) - - async def test_execute_process_fail(self): - with pytest.raises( - ServiceException, - match=( - r"400: Invalid parameterization for process 'primes_between': " - r"1 validation error for ProcessInputs\n" - r"min_val" - ), - ): - await self.service.execute_process( - process_id="primes_between", - process_request=ProcessRequest(inputs=dict(min_val=-1, max_val=30)), - request=self.get_request(), - ) - - async def test_execute_process_base_model_input(self): - job_info = await self.service.execute_process( - process_id="return_base_model", - process_request=ProcessRequest( - inputs={ - "scene_spec": { - "threshold": 0.12, - "factor": 2, - }, - } - ), - request=self.get_request(), - ) - self.assertIsInstance(job_info, JobInfo) - - async def test_get_jobs(self): - job_list = await self.service.get_jobs(request=self.get_request()) - self.assertIsInstance(job_list, JobList) - - async def test_get_job(self): - job_info_0 = await self.service.execute_process( - process_id="primes_between", - process_request=ProcessRequest(), - request=self.get_request(), - ) - job_info = await self.service.get_job( - job_id=job_info_0.jobID, request=self.get_request() - ) - self.assertIsInstance(job_info, JobInfo) - self.assertEqual("primes_between", job_info.processID) - self.assertEqual(job_info_0.jobID, job_info.jobID) - - async def test_get_job_results(self): - job_info = await self.service.execute_process( - process_id="primes_between", - process_request=ProcessRequest(inputs={"max_val": 20}), - request=self.get_request(), - ) - job_id = job_info.jobID - while job_info.status in (JobStatus.accepted, JobStatus.running): - job_info = await self.service.get_job( - job_id=job_id, request=self.get_request() - ) - self.assertEqual(JobStatus.successful, job_info.status) - job_results = await self.service.get_job_results( - job_id=job_id, request=self.get_request() - ) - self.assertIsInstance(job_results, JobResults) - self.assertEqual( - {"return_value": [2, 3, 5, 7, 11, 13, 17, 19]}, - job_results.model_dump(mode="python"), - ) diff --git a/s2gos-server/src/tests/services/local/test_testing.py b/s2gos-server/src/tests/services/local/test_testing.py deleted file mode 100644 index 86293da..0000000 --- a/s2gos-server/src/tests/services/local/test_testing.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import IsolatedAsyncioTestCase, TestCase - -from s2gos_common.models import ( - InputDescription, - JobResults, - Link, - ProcessDescription, - ProcessList, - ProcessRequest, -) -from s2gos_common.process import Job, Process -from s2gos_server.services.local.testing import SceneSpec -from s2gos_server.services.local.testing import service as testing_service - - -class TestingFunctionsTest(TestCase): - def setUp(self): - self.registry = testing_service.process_registry - - def test_run_sleep_a_while(self): - process = self.registry.get("sleep_a_while") - self.assertIsInstance(process, Process) - job = Job.create(process, ProcessRequest(inputs={"duration": 0.05})) - job_results = job.run() - self.assertIsInstance(job_results, JobResults) - - def test_run_primes_between(self): - process = self.registry.get("primes_between") - self.assertIsInstance(process, Process) - job = Job.create(process, ProcessRequest()) - job_results = job.run() - self.assertIsInstance(job_results, JobResults) - - def test_run_return_base_model(self): - process = self.registry.get("return_base_model") - self.assertIsInstance(process, Process) - job = Job.create( - process, - ProcessRequest(inputs={"scene_spec": SceneSpec(threshold=0.2, factor=2)}), - ) - job_results = job.run() - self.assertIsInstance(job_results, JobResults) - - def test_run_simulate_scene(self): - inputs = { - "var_names": "a, b", - "bbox": [-10, 30, 5, 45], - "resolution": 1, - "start_date": "2025-01-01", - "end_date": "2025-01-03", - "periodicity": 1, - "output_path": None, - } - - process = self.registry.get("simulate_scene") - self.assertIsInstance(process, Process) - job = Job.create(process, ProcessRequest(inputs=inputs)) - job_results = job.run() - self.assertIsInstance(job_results, JobResults) - json_dict = job_results.model_dump(mode="json") - self.assertIsInstance(json_dict, dict) - self.assertIsInstance(json_dict.get("return_value"), dict) - link = Link(**json_dict.get("return_value")) - self.assertIsInstance(link.href, str) - self.assertTrue(link.href.startswith("memory://")) - self.assertTrue(link.href.endswith(".zarr")) - try: - import xarray as xr - - ds = xr.open_dataset(link.href) - self.assertIsInstance(ds, xr.Dataset) - self.assertEqual({"time": 2, "lat": 15, "lon": 15}, ds.sizes) - self.assertEqual({"time", "lat", "lon"}, set(ds.coords.keys())) - self.assertEqual({"a", "b"}, set(ds.data_vars.keys())) - except ImportError: - pass - - -class TestingServiceTest(IsolatedAsyncioTestCase): - async def test_get_processes(self): - class MockRequest: - # noinspection PyMethodMayBeStatic - def url_for(self, name, **_params): - return f"https://api.com/{name}" - - process_list = await testing_service.get_processes(request=MockRequest()) - self.assertIsInstance(process_list, ProcessList) - process_dict = {v.id: v for v in process_list.processes} - self.assertEqual( - { - "sleep_a_while", - "primes_between", - "simulate_scene", - "return_base_model", - }, - set(process_dict.keys()), - ) - - async def test_get_process(self): - process = await testing_service.get_process(process_id="simulate_scene") - self.assertIsInstance(process, ProcessDescription) - self.assertIsInstance(process.inputs, dict) - - bbox_input = process.inputs.get("bbox") - self.assertIsInstance(bbox_input, InputDescription) - self.assertEqual("Bounding box", bbox_input.title) - self.assertEqual( - "Bounding box in geographical coordinates.", bbox_input.description - ) - self.assertEqual( - { - "type": "array", - "default": [-180, -90, 180, 90], - "format": "bbox", - "items": {"type": "number"}, - "minItems": 4, - "maxItems": 4, - }, - bbox_input.schema_.model_dump( - mode="json", - exclude_defaults=True, - exclude_none=True, - ), - ) - - start_date_input = process.inputs.get("start_date") - self.assertIsInstance(start_date_input, InputDescription) - self.assertEqual("Start date", start_date_input.title) - self.assertEqual(None, start_date_input.description) - self.assertEqual( - { - "type": "string", - "format": "date", - "default": "2025-01-01", - }, - start_date_input.schema_.model_dump( - mode="json", - exclude_defaults=True, - exclude_none=True, - ), - ) diff --git a/s2gos-server/src/tests/test_app.py b/s2gos-server/src/tests/test_app.py deleted file mode 100644 index aac52ae..0000000 --- a/s2gos-server/src/tests/test_app.py +++ /dev/null @@ -1,108 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import logging -from unittest import TestCase - -from fastapi.testclient import TestClient - -from s2gos_server.logging import LogMessageFilter -from s2gos_server.main import app -from s2gos_server.provider import ServiceProvider -from s2gos_server.services.local.testing import service - -client = TestClient(app) - - -class AppTest(TestCase): - def setUp(self): - ServiceProvider.set_instance(service) - - def test_get_capabilities(self): - response = client.get("/") - self.assertEqual(200, response.status_code) - - def test_get_conformance(self): - response = client.get("/conformance") - self.assertEqual(200, response.status_code) - - def test_get_processes(self): - response = client.get("/processes") - self.assertEqual(200, response.status_code) - - def test_get_process(self): - response = client.get("/processes/primes_between") - self.assertEqual(200, response.status_code) - - def test_get_process_fail(self): - response = client.get("/processes/primos_batman") - self.assertEqual(404, response.status_code) - self.assertEqual( - { - "type": "ApiError", - "status": 404, - "title": "Not Found", - "detail": "Process 'primos_batman' does not exist", - }, - response.json(), - ) - - def test_execute_process(self): - response = client.post("/processes/primes_between/execution", json={}) - self.assertEqual(201, response.status_code) - - def test_get_jobs(self): - response = client.post("/processes/primes_between/execution", json={}) - _job_id = response.json()["jobID"] - response = client.get("/jobs") - self.assertEqual(200, response.status_code) - - def test_get_job(self): - response = client.post("/processes/primes_between/execution", json={}) - job_id = response.json()["jobID"] - response = client.get(f"/jobs/{job_id}") - self.assertEqual(200, response.status_code) - - def test_dismiss_job(self): - response = client.post("/processes/primes_between/execution", json={}) - job_id = response.json()["jobID"] - response = client.delete(f"/jobs/{job_id}") - self.assertEqual(200, response.status_code) - - def test_get_job_results(self): - response = client.post("/processes/primes_between/execution", json={}) - job_info = response.json() - job_id = response.json()["jobID"] - while job_info.get("status") != "successful": - response = client.get(f"/jobs/{job_id}") - job_info = response.json() - response = client.get(f"/jobs/{job_id}/results") - self.assertEqual(200, response.status_code) - - -class LogMessageFilterTest(TestCase): - def test_filter_works(self): - class MyHandler(logging.Handler): - def __init__(self): - super().__init__() - self.records: list[logging.LogRecord] = [] - - def emit(self, record: logging.LogRecord): - self.records.append(record) - - handler = MyHandler() - logger = logging.getLogger("uvicorn.access") - logger.addHandler(handler) - logger.addFilter(LogMessageFilter("GET /jobs/")) - logger.setLevel(logging.INFO) - # excluded - logger.info('INFO: 127.0.0.1:53529 - "GET /jobs/job_8 HTTP/1.1" 200 OK') - logger.info('INFO: 127.0.0.1:53529 - "GET /jobs/job_9 HTTP/1.1" 200 OK') - self.assertEqual(0, len(handler.records)) - # included - logger.info('INFO: 127.0.0.1:53529 - "GET /jobs HTTP/1.1" 200 OK') - self.assertEqual(1, len(handler.records)) - # included - logger.info('INFO: 127.0.0.1:53529 - "GET /processes HTTP/1.1" 200 OK') - self.assertEqual(2, len(handler.records)) diff --git a/s2gos-server/src/tests/test_exceptions.py b/s2gos-server/src/tests/test_exceptions.py deleted file mode 100644 index a14838f..0000000 --- a/s2gos-server/src/tests/test_exceptions.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -from s2gos_common.models import ApiError -from s2gos_server.exceptions import ServiceException - - -class JSONContentExceptionTest(TestCase): - def test_content_is_api_error_model(self): - exc = ServiceException(401, "Bibo not authorized") - self.assertEqual( - ApiError( - type="ApiError", - status=401, - title="Unauthorized", - detail="Bibo not authorized", - ), - exc.content, - ) - - def test_includes_traceback(self): - try: - raise RuntimeError("Argh!") - except Exception as e: - exc = ServiceException(500, "Internal error", exception=e) - self.assertIsInstance(exc.content, ApiError) - self.assertIsInstance(exc.content.traceback, list) diff --git a/s2gos-server/src/tests/test_main.py b/s2gos-server/src/tests/test_main.py deleted file mode 100644 index 4947672..0000000 --- a/s2gos-server/src/tests/test_main.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -from fastapi import FastAPI - -from s2gos_server.main import app - - -class MainTest(TestCase): - def test_service_provider_init_ok(self): - self.assertIsInstance(app, FastAPI) diff --git a/s2gos-server/src/tests/test_provider.py b/s2gos-server/src/tests/test_provider.py deleted file mode 100644 index 9ca91bd..0000000 --- a/s2gos-server/src/tests/test_provider.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -import pytest - -from s2gos_common.util.testing import set_env_cm -from s2gos_server.exceptions import ServiceConfigException -from s2gos_server.provider import ServiceProvider, get_service -from s2gos_server.services.local import LocalService -from s2gos_server.services.local.testing import service as test_service - - -class ServiceProviderTest(TestCase): - def setUp(self): - ServiceProvider._service = None - - def test_set_directly(self): - service = LocalService(title="Test service") - ServiceProvider.set_instance(service) - self.assertIs(service, ServiceProvider.get_instance()) - self.assertIs(service, get_service()) - - # noinspection PyMethodMayBeStatic - def test_set_from_env_var(self): - with set_env_cm(S2GOS_SERVICE="s2gos_server.services.local.testing:service"): - self.assertIs(test_service, ServiceProvider.get_instance()) - self.assertIs(test_service, get_service()) - - # noinspection PyMethodMayBeStatic - def test_not_set(self): - with set_env_cm(S2GOS_SERVICE=None): - with pytest.raises( - ServiceConfigException, - match=( - "Service not specified. " - "The service must be passed in the form " - "'path.to.module:service'" - ), - ): - ServiceProvider.get_instance() From f5685689b23cefa7edf50d3819960d647e88bef1 Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Thu, 6 Nov 2025 19:20:21 +0100 Subject: [PATCH 05/16] Package `s2gos-server` now uses the Eozilla package `wraptile` --- CHANGES.md | 1 + s2gos-client/src/s2gos_client/__init__.py | 5 +- s2gos-client/src/s2gos_client/api.py | 5 +- s2gos-server/src/s2gos_server/cli.py | 128 +--------------------- s2gos-server/src/tests/test_cli.py | 79 +------------ 5 files changed, 10 insertions(+), 208 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3a5bb2e..754bd73 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ - Implementation code moved to [Eozilla](https://github.com/eo-tools/eozilla) (#39): - Package `s2gos-client` now uses the Eozilla package `cuiman`. + - Package `s2gos-server` now uses the Eozilla package `wraptile`. - Package `s2gos-app-ex` now uses the Eozilla package `procodile`. ## Changes in version 0.0.5 diff --git a/s2gos-client/src/s2gos_client/__init__.py b/s2gos-client/src/s2gos_client/__init__.py index 902c555..6d179ca 100644 --- a/s2gos-client/src/s2gos_client/__init__.py +++ b/s2gos-client/src/s2gos_client/__init__.py @@ -4,10 +4,7 @@ from importlib.metadata import version -from .api import AsyncClient -from .api import Client -from .api import ClientConfig -from .api import ClientError +from .api import AsyncClient, Client, ClientConfig, ClientError __version__ = version("s2gos-client") diff --git a/s2gos-client/src/s2gos_client/api.py b/s2gos-client/src/s2gos_client/api.py index c077b59..b06fd69 100644 --- a/s2gos-client/src/s2gos_client/api.py +++ b/s2gos-client/src/s2gos_client/api.py @@ -2,10 +2,7 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -from cuiman.api import Client -from cuiman.api import AsyncClient -from cuiman.api import ClientConfig -from cuiman.api import ClientError +from cuiman.api import AsyncClient, Client, ClientConfig, ClientError __all__ = [ "AsyncClient", diff --git a/s2gos-server/src/s2gos_server/cli.py b/s2gos-server/src/s2gos_server/cli.py index a1d75a8..311e92c 100644 --- a/s2gos-server/src/s2gos_server/cli.py +++ b/s2gos-server/src/s2gos_server/cli.py @@ -2,133 +2,13 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -import logging -from typing import Annotated, Optional +from wraptile.cli import get_cli -import typer +from s2gos_server import __version__ as version -from s2gos_server.constants import ( - DEFAULT_HOST, - DEFAULT_PORT, - ENV_VAR_SERVER_HOST, - ENV_VAR_SERVER_PORT, - ENV_VAR_SERVICE, -) -from s2gos_server.logging import LogMessageFilter - -CLI_HELP = """ -Server for the ESA synthetic scene generator service DTE-S2GOS. - -The server provides a restful API that should be almost compliant -with the OGC API - Processes - Part 1: Core Standard. - -For details see https://ogcapi.ogc.org/processes/. - -The service instance may be followed by a `--` to pass one or more -service-specific arguments and options. - -Note that the service arguments may also be given by the -environment variable `{service_env_var}`. -""".format( - service_env_var=ENV_VAR_SERVICE, -) - - -def parse_cli_service_options( - _ctx: typer.Context, kwargs: Optional[list[str]] = None -) -> list[str]: - import os - import shlex - - if not kwargs: - return [] - service_args = os.environ.get(ENV_VAR_SERVICE) - if kwargs == [service_args]: - return shlex.split(service_args) - return kwargs - - -cli = typer.Typer(name="s2gos-server", help=CLI_HELP, invoke_without_command=True) - -cli_host_option = typer.Option( - envvar=ENV_VAR_SERVER_HOST, - help="Host address.", -) -cli_port_option = typer.Option( - envvar=ENV_VAR_SERVER_PORT, - help="Port number.", -) -cli_service_arg = typer.Argument( - callback=parse_cli_service_options, - envvar=ENV_VAR_SERVICE, - help=( - "Service instance optionally followed by `--` to pass " - "service-specific arguments and options. SERVICE should " - "have the form `path.to.module:service`." - ), - metavar="SERVICE [-- SERVICE-OPTIONS]", -) - - -@cli.callback() -def main( - _ctx: typer.Context, - version_: Annotated[ - bool, typer.Option("--version", help="Show version and exit.") - ] = False, -): - if version_: - from importlib.metadata import version - - typer.echo(version("s2gos-server")) - raise typer.Exit() - - -@cli.command() -def run( - host: Annotated[str, cli_host_option] = DEFAULT_HOST, - port: Annotated[int, cli_port_option] = DEFAULT_PORT, - service: Annotated[Optional[list[str]], cli_service_arg] = None, -): - """Run server in production mode.""" - run_server( - host=host, - port=port, - service=service, - reload=False, - ) - - -@cli.command() -def dev( - host: Annotated[str, cli_host_option] = DEFAULT_HOST, - port: Annotated[int, cli_port_option] = DEFAULT_PORT, - service: Annotated[Optional[list[str]], cli_service_arg] = None, -): - """Run server in development mode.""" - run_server( - host=host, - port=port, - service=service, - reload=True, - ) - - -def run_server(**kwargs): - import os - import shlex - - import uvicorn - - service = kwargs.pop("service", None) - if isinstance(service, list) and service: - os.environ[ENV_VAR_SERVICE] = shlex.join(service) - - # Apply the filter to the uvicorn.access logger - logging.getLogger("uvicorn.access").addFilter(LogMessageFilter("/jobs")) - - uvicorn.run("s2gos_server.main:app", **kwargs) +cli = get_cli("s2gos-server", version=version) +__all__ = ["cli"] if __name__ == "__main__": # pragma: no cover cli() diff --git a/s2gos-server/src/tests/test_cli.py b/s2gos-server/src/tests/test_cli.py index 05cb361..eb050c8 100644 --- a/s2gos-server/src/tests/test_cli.py +++ b/s2gos-server/src/tests/test_cli.py @@ -2,81 +2,8 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -from unittest import TestCase -from unittest.mock import MagicMock, patch +import s2gos_client.cli -import typer -from typer.testing import CliRunner -from s2gos_common.util.testing import set_env_cm -from s2gos_server import __version__ -from s2gos_server.cli import cli, parse_cli_service_options -from s2gos_server.constants import ENV_VAR_SERVICE - -runner = CliRunner() - - -class CliTest(TestCase): - def test_help(self): - result = runner.invoke(cli, ["--help"]) - self.assertEqual(0, result.exit_code) - self.assertIn("Server for the ESA synthetic", result.output) - - def test_version(self): - result = runner.invoke(cli, ["--version"]) - self.assertEqual(0, result.exit_code) - self.assertEqual(__version__ + "\n", result.output) - - def test_parse_cli_service_options(self): - ctx = typer.Context( - cli, - allow_extra_args=False, - allow_interspersed_args=False, - ignore_unknown_options=False, - ) - env_var_value = "my.service:service --workers=5 --threads" - with set_env_cm(**{ENV_VAR_SERVICE: env_var_value}): - self.assertEqual([], parse_cli_service_options(ctx, None)) - self.assertEqual([], parse_cli_service_options(ctx, [])) - self.assertEqual( - ["another:service", "--name=bibo"], - parse_cli_service_options(ctx, ["another:service", "--name=bibo"]), - ) - self.assertEqual( - ["my.service:service", "--workers=5", "--threads"], - parse_cli_service_options(ctx, [env_var_value]), - ) - - @patch("uvicorn.run") - def test_run(self, mock: MagicMock): - result = runner.invoke( - cli, - [ - "run", - "--", - "s2gos_server.services.local.testing:service", - "--processes", - "--max-workers=4", - ], - ) - self.assertEqual(0, result.exit_code) - mock.assert_called_with( - "s2gos_server.main:app", host="127.0.0.1", port=8008, reload=False - ) - - @patch("uvicorn.run") - def test_dev(self, mock: MagicMock): - result = runner.invoke( - cli, - [ - "dev", - "--", - "s2gos_server.services.local.testing:service", - "--no-processes", - "--max-workers=4", - ], - ) - self.assertEqual(0, result.exit_code) - mock.assert_called_with( - "s2gos_server.main:app", host="127.0.0.1", port=8008, reload=True - ) +def test_cli_ok(): + assert {"cli"}.issubset(dir(s2gos_client.cli)) From 172c8996e92688d4b97880cd0d19d5d6ad875627 Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Fri, 7 Nov 2025 12:58:33 +0100 Subject: [PATCH 06/16] Updated CLI summary --- s2gos-client/src/s2gos_client/cli.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/s2gos-client/src/s2gos_client/cli.py b/s2gos-client/src/s2gos_client/cli.py index 177df60..ab7d70f 100644 --- a/s2gos-client/src/s2gos_client/cli.py +++ b/s2gos-client/src/s2gos_client/cli.py @@ -6,7 +6,11 @@ from s2gos_server import __version__ as version -cli = get_cli("s2gos-client", version=version) +cli = get_cli( + "s2gos-client", + summary="Interact with the ESA DTE S2GOS service.", + version=version, +) __all__ = [ "cli", From ea8b94c6a1020881d8a8306cf7a22bc629993a5d Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Mon, 10 Nov 2025 16:01:48 +0100 Subject: [PATCH 07/16] Removed unused stuff, updated still-valid stuff --- notebooks/client-api-airflow.ipynb | 2 +- notebooks/client-api.ipynb | 88 +- notebooks/client-cli.ipynb | 388 +- notebooks/client-gui.ipynb | 194 +- pixi.lock | 41 +- pyproject.toml | 71 +- s2gos-airflow/.gitignore | 5 - s2gos-airflow/LICENSE | 201 - s2gos-airflow/README.md | 80 - s2gos-airflow/dags/primes_between.py | 28 - s2gos-airflow/dags/return_base_model.py | 32 - s2gos-airflow/dags/simulate_scene.py | 70 - s2gos-airflow/dags/sleep_a_while.py | 28 - .../notebooks/airflow-client-test.ipynb | 178 - s2gos-airflow/notebooks/airflow-setup.ipynb | 1455 ------ s2gos-airflow/pixi.lock | 3961 ----------------- s2gos-airflow/pyproject.toml | 53 - s2gos-airflow/tests/dags/__init__.py | 0 s2gos-airflow/tests/dags/test_example_dag.py | 8 - s2gos-airflow/tests/test_airflow_service.py | 0 s2gos-app-ex/Dockerfile | 18 - s2gos-app-ex/LICENSE | 201 - s2gos-app-ex/README.md | 10 - s2gos-app-ex/pixi.lock | 1222 ----- s2gos-app-ex/pyproject.toml | 92 - s2gos-app-ex/src/s2gos_app_ex/cli.py | 13 - s2gos-app-ex/src/s2gos_app_ex/processes.py | 81 - s2gos-client/pyproject.toml | 10 +- s2gos-client/src/s2gos_client/__init__.py | 5 + s2gos-client/src/s2gos_client/cli.py | 10 +- .../tests}/__init__.py | 0 .../tests}/py.typed | 0 s2gos-client/{src => }/tests/test_api.py | 0 s2gos-client/{src => }/tests/test_cli.py | 0 s2gos-client/{src => }/tests/test_gui.py | 0 s2gos-common/LICENSE | 201 - s2gos-common/README.md | 4 - s2gos-common/pyproject.toml | 70 - s2gos-common/src/s2gos_common/__init__.py | 39 - s2gos-common/src/s2gos_common/models.py | 315 -- .../src/s2gos_common/process/__init__.py | 21 - .../src/s2gos_common/process/cli/__init__.py | 6 - .../src/s2gos_common/process/cli/cli.py | 202 - s2gos-common/src/s2gos_common/process/job.py | 348 -- .../src/s2gos_common/process/process.py | 268 -- .../src/s2gos_common/process/registry.py | 99 - .../src/s2gos_common/process/reporter.py | 67 - .../src/s2gos_common/process/request.py | 256 -- .../src/s2gos_common/process/schema.py | 108 - s2gos-common/src/s2gos_common/service.py | 99 - .../src/s2gos_common/util/__init__.py | 3 - .../src/s2gos_common/util/cli/__init__.py | 0 .../src/s2gos_common/util/cli/group.py | 53 - .../src/s2gos_common/util/cli/parameters.py | 43 - s2gos-common/src/s2gos_common/util/dynimp.py | 72 - s2gos-common/src/s2gos_common/util/obj.py | 138 - s2gos-common/src/s2gos_common/util/testing.py | 64 - s2gos-common/src/tests/__init__.py | 3 - s2gos-common/src/tests/process/__init__.py | 3 - .../src/tests/process/cli/__init__.py | 3 - .../src/tests/process/cli/test_cli.py | 186 - s2gos-common/src/tests/process/test_job.py | 257 -- .../src/tests/process/test_process.py | 449 -- .../src/tests/process/test_pydantic.py | 28 - .../src/tests/process/test_registry.py | 49 - .../src/tests/process/test_reporter.py | 72 - .../src/tests/process/test_request.py | 371 -- s2gos-common/src/tests/process/test_schema.py | 109 - s2gos-common/src/tests/test_models.py | 75 - s2gos-common/src/tests/test_service.py | 28 - s2gos-common/src/tests/test_testing.py | 32 - s2gos-common/src/tests/util/__init__.py | 0 s2gos-common/src/tests/util/cli/__init__.py | 0 s2gos-common/src/tests/util/cli/test_group.py | 57 - s2gos-common/src/tests/util/test_dynimp.py | 60 - s2gos-common/src/tests/util/test_obj.py | 93 - s2gos-server/pyproject.toml | 9 +- s2gos-server/src/s2gos_server/cli.py | 4 +- s2gos-server/src/tests/__init__.py | 3 - .../src => s2gos-server}/tests/__init__.py | 0 .../tests/py.typed | 0 s2gos-server/{src => }/tests/test_cli.py | 4 +- tools/common.py | 159 +- tools/gen_client.py | 337 -- tools/gen_dags.py | 108 - tools/gen_models.py | 37 - tools/gen_server.py | 203 - tools/openapi.py | 73 - tools/openapi.yaml | 922 ---- tools/sync_versions.py | 2 +- 90 files changed, 533 insertions(+), 14224 deletions(-) delete mode 100644 s2gos-airflow/.gitignore delete mode 100644 s2gos-airflow/LICENSE delete mode 100644 s2gos-airflow/README.md delete mode 100644 s2gos-airflow/dags/primes_between.py delete mode 100644 s2gos-airflow/dags/return_base_model.py delete mode 100644 s2gos-airflow/dags/simulate_scene.py delete mode 100644 s2gos-airflow/dags/sleep_a_while.py delete mode 100644 s2gos-airflow/notebooks/airflow-client-test.ipynb delete mode 100644 s2gos-airflow/notebooks/airflow-setup.ipynb delete mode 100644 s2gos-airflow/pixi.lock delete mode 100644 s2gos-airflow/pyproject.toml delete mode 100644 s2gos-airflow/tests/dags/__init__.py delete mode 100644 s2gos-airflow/tests/dags/test_example_dag.py delete mode 100644 s2gos-airflow/tests/test_airflow_service.py delete mode 100644 s2gos-app-ex/Dockerfile delete mode 100644 s2gos-app-ex/LICENSE delete mode 100644 s2gos-app-ex/README.md delete mode 100644 s2gos-app-ex/pixi.lock delete mode 100644 s2gos-app-ex/pyproject.toml delete mode 100644 s2gos-app-ex/src/s2gos_app_ex/cli.py delete mode 100644 s2gos-app-ex/src/s2gos_app_ex/processes.py rename {s2gos-app-ex/src/s2gos_app_ex => s2gos-client/tests}/__init__.py (100%) rename {s2gos-common/src/s2gos_common => s2gos-client/tests}/py.typed (100%) rename s2gos-client/{src => }/tests/test_api.py (100%) rename s2gos-client/{src => }/tests/test_cli.py (100%) rename s2gos-client/{src => }/tests/test_gui.py (100%) delete mode 100644 s2gos-common/LICENSE delete mode 100644 s2gos-common/README.md delete mode 100644 s2gos-common/pyproject.toml delete mode 100644 s2gos-common/src/s2gos_common/__init__.py delete mode 100644 s2gos-common/src/s2gos_common/models.py delete mode 100644 s2gos-common/src/s2gos_common/process/__init__.py delete mode 100644 s2gos-common/src/s2gos_common/process/cli/__init__.py delete mode 100644 s2gos-common/src/s2gos_common/process/cli/cli.py delete mode 100644 s2gos-common/src/s2gos_common/process/job.py delete mode 100644 s2gos-common/src/s2gos_common/process/process.py delete mode 100644 s2gos-common/src/s2gos_common/process/registry.py delete mode 100644 s2gos-common/src/s2gos_common/process/reporter.py delete mode 100644 s2gos-common/src/s2gos_common/process/request.py delete mode 100644 s2gos-common/src/s2gos_common/process/schema.py delete mode 100644 s2gos-common/src/s2gos_common/service.py delete mode 100644 s2gos-common/src/s2gos_common/util/__init__.py delete mode 100644 s2gos-common/src/s2gos_common/util/cli/__init__.py delete mode 100644 s2gos-common/src/s2gos_common/util/cli/group.py delete mode 100644 s2gos-common/src/s2gos_common/util/cli/parameters.py delete mode 100644 s2gos-common/src/s2gos_common/util/dynimp.py delete mode 100644 s2gos-common/src/s2gos_common/util/obj.py delete mode 100644 s2gos-common/src/s2gos_common/util/testing.py delete mode 100644 s2gos-common/src/tests/__init__.py delete mode 100644 s2gos-common/src/tests/process/__init__.py delete mode 100644 s2gos-common/src/tests/process/cli/__init__.py delete mode 100644 s2gos-common/src/tests/process/cli/test_cli.py delete mode 100644 s2gos-common/src/tests/process/test_job.py delete mode 100644 s2gos-common/src/tests/process/test_process.py delete mode 100644 s2gos-common/src/tests/process/test_pydantic.py delete mode 100644 s2gos-common/src/tests/process/test_registry.py delete mode 100644 s2gos-common/src/tests/process/test_reporter.py delete mode 100644 s2gos-common/src/tests/process/test_request.py delete mode 100644 s2gos-common/src/tests/process/test_schema.py delete mode 100644 s2gos-common/src/tests/test_models.py delete mode 100644 s2gos-common/src/tests/test_service.py delete mode 100644 s2gos-common/src/tests/test_testing.py delete mode 100644 s2gos-common/src/tests/util/__init__.py delete mode 100644 s2gos-common/src/tests/util/cli/__init__.py delete mode 100644 s2gos-common/src/tests/util/cli/test_group.py delete mode 100644 s2gos-common/src/tests/util/test_dynimp.py delete mode 100644 s2gos-common/src/tests/util/test_obj.py delete mode 100644 s2gos-server/src/tests/__init__.py rename {s2gos-client/src => s2gos-server}/tests/__init__.py (100%) rename s2gos-airflow/tests/__init__.py => s2gos-server/tests/py.typed (100%) rename s2gos-server/{src => }/tests/test_cli.py (73%) delete mode 100644 tools/gen_client.py delete mode 100644 tools/gen_dags.py delete mode 100644 tools/gen_models.py delete mode 100644 tools/gen_server.py delete mode 100644 tools/openapi.py delete mode 100644 tools/openapi.yaml diff --git a/notebooks/client-api-airflow.ipynb b/notebooks/client-api-airflow.ipynb index 0f7a5bd..79fa104 100644 --- a/notebooks/client-api-airflow.ipynb +++ b/notebooks/client-api-airflow.ipynb @@ -22,7 +22,7 @@ "\n", "```commandline\n", "pixi shell\n", - "s2gos-server run -- s2gos_server.services.airflow:service --airflow-password=a8e7f4bb230\n", + "s2gos-server run -- wraptile.services.airflow:service --airflow-password=a8e7f4bb230\n", "```\n", "\n", "Get the airflow user password from `s2gos-airflow/.airflow/simple_auth_manager_passwords.json.generated`." diff --git a/notebooks/client-api.ipynb b/notebooks/client-api.ipynb index bb24d58..e257039 100644 --- a/notebooks/client-api.ipynb +++ b/notebooks/client-api.ipynb @@ -24,7 +24,7 @@ "with a test configuration:\n", "\n", "```bash\n", - "s2gos-server run -- s2gos_server.services.local.testing:service\n", + "s2gos-server run -- wraptile.services.local.testing:service\n", "```" ] }, @@ -36,7 +36,7 @@ "outputs": [], "source": [ "from s2gos_client import Client\n", - "from s2gos_common.models import ProcessRequest" + "from gavicore.models import ProcessRequest" ] }, { @@ -48,12 +48,12 @@ { "data": { "application/json": { - "access_token": "1234", + "access_token": "ip245", "server_url": "http://127.0.0.1:8008", "user_name": "bibo" }, "text/plain": [ - "" + "" ] }, "execution_count": 2, @@ -180,10 +180,10 @@ "type": "application/json" } ], - "title": "S2GOS API Server (local dummy for testing)" + "title": "Eozilla API Server (local dummy for testing)" }, "text/plain": [ - "Capabilities(title='S2GOS API Server (local dummy for testing)', description='Local test server implementing the OGC API - Processes 1.0 Standard', links=[Link(href='http://127.0.0.1:8008/', rel='self', type='application/json', hreflang='en', title='get_capabilities'), Link(href='http://127.0.0.1:8008/openapi.json', rel='service', type='application/json', hreflang='en', title='openapi'), Link(href='http://127.0.0.1:8008/docs', rel='service', type='text/html', hreflang='en', title='swagger_ui_html'), Link(href='http://127.0.0.1:8008/docs/oauth2-redirect', rel='service', type='text/html', hreflang='en', title='swagger_ui_redirect'), Link(href='http://127.0.0.1:8008/redoc', rel='service', type='text/html', hreflang='en', title='redoc_html'), Link(href='http://127.0.0.1:8008/', rel='service', type='application/json', hreflang='en', title='get_capabilities'), Link(href='http://127.0.0.1:8008/conformance', rel='service', type='application/json', hreflang='en', title='get_conformance'), Link(href='http://127.0.0.1:8008/processes', rel='service', type='application/json', hreflang='en', title='get_processes'), Link(href='http://127.0.0.1:8008/processes/{processID}', rel='service', type='application/json', hreflang='en', title='get_process'), Link(href='http://127.0.0.1:8008/processes/{processID}/execution', rel='service', type='application/json', hreflang='en', title='execute_process'), Link(href='http://127.0.0.1:8008/jobs', rel='service', type='application/json', hreflang='en', title='get_jobs'), Link(href='http://127.0.0.1:8008/jobs/{jobId}', rel='service', type='application/json', hreflang='en', title='get_job'), Link(href='http://127.0.0.1:8008/jobs/{jobId}', rel='service', type='application/json', hreflang='en', title='dismiss_job'), Link(href='http://127.0.0.1:8008/jobs/{jobId}/results', rel='service', type='application/json', hreflang='en', title='get_job_results')])" + "Capabilities(title='Eozilla API Server (local dummy for testing)', description='Local test server implementing the OGC API - Processes 1.0 Standard', links=[Link(href='http://127.0.0.1:8008/', rel='self', type='application/json', hreflang='en', title='get_capabilities'), Link(href='http://127.0.0.1:8008/openapi.json', rel='service', type='application/json', hreflang='en', title='openapi'), Link(href='http://127.0.0.1:8008/docs', rel='service', type='text/html', hreflang='en', title='swagger_ui_html'), Link(href='http://127.0.0.1:8008/docs/oauth2-redirect', rel='service', type='text/html', hreflang='en', title='swagger_ui_redirect'), Link(href='http://127.0.0.1:8008/redoc', rel='service', type='text/html', hreflang='en', title='redoc_html'), Link(href='http://127.0.0.1:8008/', rel='service', type='application/json', hreflang='en', title='get_capabilities'), Link(href='http://127.0.0.1:8008/conformance', rel='service', type='application/json', hreflang='en', title='get_conformance'), Link(href='http://127.0.0.1:8008/processes', rel='service', type='application/json', hreflang='en', title='get_processes'), Link(href='http://127.0.0.1:8008/processes/{processID}', rel='service', type='application/json', hreflang='en', title='get_process'), Link(href='http://127.0.0.1:8008/processes/{processID}/execution', rel='service', type='application/json', hreflang='en', title='execute_process'), Link(href='http://127.0.0.1:8008/jobs', rel='service', type='application/json', hreflang='en', title='get_jobs'), Link(href='http://127.0.0.1:8008/jobs/{jobId}', rel='service', type='application/json', hreflang='en', title='get_job'), Link(href='http://127.0.0.1:8008/jobs/{jobId}', rel='service', type='application/json', hreflang='en', title='dismiss_job'), Link(href='http://127.0.0.1:8008/jobs/{jobId}/results', rel='service', type='application/json', hreflang='en', title='get_job_results')])" ] }, "execution_count": 3, @@ -398,17 +398,17 @@ { "data": { "application/json": { - "created": "2025-10-07T14:27:18.702704Z", + "created": "2025-11-10T14:58:35.373594Z", "jobID": "job_0", "processID": "sleep_a_while", "progress": 0, - "started": "2025-10-07T14:27:18.703480Z", + "started": "2025-11-10T14:58:35.374333Z", "status": "running", "type": "process", - "updated": "2025-10-07T14:27:18.703722Z" + "updated": "2025-11-10T14:58:35.374437Z" }, "text/plain": [ - "JobInfo(processID='sleep_a_while', type=, jobID='job_0', status=, message=None, created=datetime.datetime(2025, 10, 7, 14, 27, 18, 702704, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 10, 7, 14, 27, 18, 703480, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 10, 7, 14, 27, 18, 703722, tzinfo=TzInfo(UTC)), progress=0, links=None, traceback=None)" + "JobInfo(processID='sleep_a_while', type=, jobID='job_0', status=, message=None, created=datetime.datetime(2025, 11, 10, 14, 58, 35, 373594, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 11, 10, 14, 58, 35, 374333, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 11, 10, 14, 58, 35, 374437, tzinfo=TzInfo(UTC)), progress=0, links=None, traceback=None)" ] }, "execution_count": 8, @@ -433,17 +433,17 @@ { "data": { "application/json": { - "created": "2025-10-07T14:27:18.729307Z", + "created": "2025-11-10T14:58:35.383115Z", "jobID": "job_1", "processID": "sleep_a_while", "progress": 0, - "started": "2025-10-07T14:27:18.730120Z", + "started": "2025-11-10T14:58:35.383514Z", "status": "running", "type": "process", - "updated": "2025-10-07T14:27:18.730187Z" + "updated": "2025-11-10T14:58:35.383554Z" }, "text/plain": [ - "JobInfo(processID='sleep_a_while', type=, jobID='job_1', status=, message=None, created=datetime.datetime(2025, 10, 7, 14, 27, 18, 729307, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 10, 7, 14, 27, 18, 730120, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 10, 7, 14, 27, 18, 730187, tzinfo=TzInfo(UTC)), progress=0, links=None, traceback=None)" + "JobInfo(processID='sleep_a_while', type=, jobID='job_1', status=, message=None, created=datetime.datetime(2025, 11, 10, 14, 58, 35, 383115, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 11, 10, 14, 58, 35, 383514, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 11, 10, 14, 58, 35, 383554, tzinfo=TzInfo(UTC)), progress=0, links=None, traceback=None)" ] }, "execution_count": 9, @@ -468,18 +468,18 @@ { "data": { "application/json": { - "created": "2025-10-07T14:27:18.752928Z", - "finished": "2025-10-07T14:27:18.753685Z", + "created": "2025-11-10T14:58:35.395356Z", + "finished": "2025-11-10T14:58:35.395876Z", "jobID": "job_2", "message": "Done", "processID": "primes_between", - "started": "2025-10-07T14:27:18.753482Z", + "started": "2025-11-10T14:58:35.395738Z", "status": "successful", "type": "process", - "updated": "2025-10-07T14:27:18.753659Z" + "updated": "2025-11-10T14:58:35.395847Z" }, "text/plain": [ - "JobInfo(processID='primes_between', type=, jobID='job_2', status=, message='Done', created=datetime.datetime(2025, 10, 7, 14, 27, 18, 752928, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 10, 7, 14, 27, 18, 753482, tzinfo=TzInfo(UTC)), finished=datetime.datetime(2025, 10, 7, 14, 27, 18, 753685, tzinfo=TzInfo(UTC)), updated=datetime.datetime(2025, 10, 7, 14, 27, 18, 753659, tzinfo=TzInfo(UTC)), progress=None, links=None, traceback=None)" + "JobInfo(processID='primes_between', type=, jobID='job_2', status=, message='Done', created=datetime.datetime(2025, 11, 10, 14, 58, 35, 395356, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 11, 10, 14, 58, 35, 395738, tzinfo=TzInfo(UTC)), finished=datetime.datetime(2025, 11, 10, 14, 58, 35, 395876, tzinfo=TzInfo(UTC)), updated=datetime.datetime(2025, 11, 10, 14, 58, 35, 395847, tzinfo=TzInfo(UTC)), progress=None, links=None, traceback=None)" ] }, "execution_count": 10, @@ -506,35 +506,35 @@ "application/json": { "jobs": [ { - "created": "2025-10-07T14:27:18.702704Z", + "created": "2025-11-10T14:58:35.373594Z", "jobID": "job_0", "processID": "sleep_a_while", "progress": 0, - "started": "2025-10-07T14:27:18.703480Z", + "started": "2025-11-10T14:58:35.374333Z", "status": "running", "type": "process", - "updated": "2025-10-07T14:27:18.703722Z" + "updated": "2025-11-10T14:58:35.374437Z" }, { - "created": "2025-10-07T14:27:18.729307Z", + "created": "2025-11-10T14:58:35.383115Z", "jobID": "job_1", "processID": "sleep_a_while", "progress": 0, - "started": "2025-10-07T14:27:18.730120Z", + "started": "2025-11-10T14:58:35.383514Z", "status": "running", "type": "process", - "updated": "2025-10-07T14:27:18.730187Z" + "updated": "2025-11-10T14:58:35.383554Z" }, { - "created": "2025-10-07T14:27:18.752928Z", - "finished": "2025-10-07T14:27:18.753685Z", + "created": "2025-11-10T14:58:35.395356Z", + "finished": "2025-11-10T14:58:35.395876Z", "jobID": "job_2", "message": "Done", "processID": "primes_between", - "started": "2025-10-07T14:27:18.753482Z", + "started": "2025-11-10T14:58:35.395738Z", "status": "successful", "type": "process", - "updated": "2025-10-07T14:27:18.753659Z" + "updated": "2025-11-10T14:58:35.395847Z" } ], "links": [ @@ -548,7 +548,7 @@ ] }, "text/plain": [ - "JobList(jobs=[JobInfo(processID='sleep_a_while', type=, jobID='job_0', status=, message=None, created=datetime.datetime(2025, 10, 7, 14, 27, 18, 702704, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 10, 7, 14, 27, 18, 703480, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 10, 7, 14, 27, 18, 703722, tzinfo=TzInfo(UTC)), progress=0, links=None, traceback=None), JobInfo(processID='sleep_a_while', type=, jobID='job_1', status=, message=None, created=datetime.datetime(2025, 10, 7, 14, 27, 18, 729307, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 10, 7, 14, 27, 18, 730120, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 10, 7, 14, 27, 18, 730187, tzinfo=TzInfo(UTC)), progress=0, links=None, traceback=None), JobInfo(processID='primes_between', type=, jobID='job_2', status=, message='Done', created=datetime.datetime(2025, 10, 7, 14, 27, 18, 752928, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 10, 7, 14, 27, 18, 753482, tzinfo=TzInfo(UTC)), finished=datetime.datetime(2025, 10, 7, 14, 27, 18, 753685, tzinfo=TzInfo(UTC)), updated=datetime.datetime(2025, 10, 7, 14, 27, 18, 753659, tzinfo=TzInfo(UTC)), progress=None, links=None, traceback=None)], links=[Link(href='http://127.0.0.1:8008/jobs', rel='self', type='application/json', hreflang='en', title='get_jobs')])" + "JobList(jobs=[JobInfo(processID='sleep_a_while', type=, jobID='job_0', status=, message=None, created=datetime.datetime(2025, 11, 10, 14, 58, 35, 373594, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 11, 10, 14, 58, 35, 374333, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 11, 10, 14, 58, 35, 374437, tzinfo=TzInfo(UTC)), progress=0, links=None, traceback=None), JobInfo(processID='sleep_a_while', type=, jobID='job_1', status=, message=None, created=datetime.datetime(2025, 11, 10, 14, 58, 35, 383115, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 11, 10, 14, 58, 35, 383514, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 11, 10, 14, 58, 35, 383554, tzinfo=TzInfo(UTC)), progress=0, links=None, traceback=None), JobInfo(processID='primes_between', type=, jobID='job_2', status=, message='Done', created=datetime.datetime(2025, 11, 10, 14, 58, 35, 395356, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 11, 10, 14, 58, 35, 395738, tzinfo=TzInfo(UTC)), finished=datetime.datetime(2025, 11, 10, 14, 58, 35, 395876, tzinfo=TzInfo(UTC)), updated=datetime.datetime(2025, 11, 10, 14, 58, 35, 395847, tzinfo=TzInfo(UTC)), progress=None, links=None, traceback=None)], links=[Link(href='http://127.0.0.1:8008/jobs', rel='self', type='application/json', hreflang='en', title='get_jobs')])" ] }, "execution_count": 11, @@ -573,18 +573,18 @@ { "data": { "application/json": { - "created": "2025-10-07T14:27:18.752928Z", - "finished": "2025-10-07T14:27:18.753685Z", + "created": "2025-11-10T14:58:35.395356Z", + "finished": "2025-11-10T14:58:35.395876Z", "jobID": "job_2", "message": "Done", "processID": "primes_between", - "started": "2025-10-07T14:27:18.753482Z", + "started": "2025-11-10T14:58:35.395738Z", "status": "successful", "type": "process", - "updated": "2025-10-07T14:27:18.753659Z" + "updated": "2025-11-10T14:58:35.395847Z" }, "text/plain": [ - "JobInfo(processID='primes_between', type=, jobID='job_2', status=, message='Done', created=datetime.datetime(2025, 10, 7, 14, 27, 18, 752928, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 10, 7, 14, 27, 18, 753482, tzinfo=TzInfo(UTC)), finished=datetime.datetime(2025, 10, 7, 14, 27, 18, 753685, tzinfo=TzInfo(UTC)), updated=datetime.datetime(2025, 10, 7, 14, 27, 18, 753659, tzinfo=TzInfo(UTC)), progress=None, links=None, traceback=None)" + "JobInfo(processID='primes_between', type=, jobID='job_2', status=, message='Done', created=datetime.datetime(2025, 11, 10, 14, 58, 35, 395356, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 11, 10, 14, 58, 35, 395738, tzinfo=TzInfo(UTC)), finished=datetime.datetime(2025, 11, 10, 14, 58, 35, 395876, tzinfo=TzInfo(UTC)), updated=datetime.datetime(2025, 11, 10, 14, 58, 35, 395847, tzinfo=TzInfo(UTC)), progress=None, links=None, traceback=None)" ] }, "execution_count": 12, @@ -632,24 +632,24 @@ "application/json": { "jobs": [ { - "created": "2025-10-07T14:27:18.702704Z", + "created": "2025-11-10T14:58:35.373594Z", "jobID": "job_0", "processID": "sleep_a_while", - "progress": 1, - "started": "2025-10-07T14:27:18.703480Z", + "progress": 0, + "started": "2025-11-10T14:58:35.374333Z", "status": "running", "type": "process", - "updated": "2025-10-07T14:27:18.804430Z" + "updated": "2025-11-10T14:58:35.374437Z" }, { - "created": "2025-10-07T14:27:18.729307Z", + "created": "2025-11-10T14:58:35.383115Z", "jobID": "job_1", "processID": "sleep_a_while", - "progress": 1, - "started": "2025-10-07T14:27:18.730120Z", + "progress": 0, + "started": "2025-11-10T14:58:35.383514Z", "status": "running", "type": "process", - "updated": "2025-10-07T14:27:18.830338Z" + "updated": "2025-11-10T14:58:35.383554Z" } ], "links": [ @@ -663,7 +663,7 @@ ] }, "text/plain": [ - "JobList(jobs=[JobInfo(processID='sleep_a_while', type=, jobID='job_0', status=, message=None, created=datetime.datetime(2025, 10, 7, 14, 27, 18, 702704, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 10, 7, 14, 27, 18, 703480, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 10, 7, 14, 27, 18, 804430, tzinfo=TzInfo(UTC)), progress=1, links=None, traceback=None), JobInfo(processID='sleep_a_while', type=, jobID='job_1', status=, message=None, created=datetime.datetime(2025, 10, 7, 14, 27, 18, 729307, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 10, 7, 14, 27, 18, 730120, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 10, 7, 14, 27, 18, 830338, tzinfo=TzInfo(UTC)), progress=1, links=None, traceback=None)], links=[Link(href='http://127.0.0.1:8008/jobs', rel='self', type='application/json', hreflang='en', title='get_jobs')])" + "JobList(jobs=[JobInfo(processID='sleep_a_while', type=, jobID='job_0', status=, message=None, created=datetime.datetime(2025, 11, 10, 14, 58, 35, 373594, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 11, 10, 14, 58, 35, 374333, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 11, 10, 14, 58, 35, 374437, tzinfo=TzInfo(UTC)), progress=0, links=None, traceback=None), JobInfo(processID='sleep_a_while', type=, jobID='job_1', status=, message=None, created=datetime.datetime(2025, 11, 10, 14, 58, 35, 383115, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 11, 10, 14, 58, 35, 383514, tzinfo=TzInfo(UTC)), finished=None, updated=datetime.datetime(2025, 11, 10, 14, 58, 35, 383554, tzinfo=TzInfo(UTC)), progress=0, links=None, traceback=None)], links=[Link(href='http://127.0.0.1:8008/jobs', rel='self', type='application/json', hreflang='en', title='get_jobs')])" ] }, "execution_count": 15, diff --git a/notebooks/client-cli.ipynb b/notebooks/client-cli.ipynb index 266e1ce..c28b80d 100644 --- a/notebooks/client-cli.ipynb +++ b/notebooks/client-cli.ipynb @@ -25,7 +25,7 @@ "with a test configuration:\n", "\n", "```bash\n", - "s2gos-server run -- s2gos_server.services.local.testing:service\n", + "s2gos-server run -- wraptile.services.local.testing:service\n", "```" ] }, @@ -42,13 +42,27 @@ " \n", " Usage: s2gos-client [OPTIONS] COMMAND [ARGS]... \n", " \n", - " `s2gos-client` is the client shell tool for the S2GOS service. \n", + " Interact with the ESA DTE S2GOS processing service. \n", " \n", - " The tool can be used to get the available processes, get process details, \n", - " execute processes, and manage the jobs originating from the latter. It \n", - " herewith resembles the functionality of the OGC API Processes - Part 1. \n", - " You can use shorter command name aliases, e.g., use command name `vr` for \n", - " `validate-request`, or `lp` for `list-processes`. \n", + " `s2gos-client` can be used to get the available processes, get process \n", + " details, execute processes, and manage the jobs originating from the latter. \n", + " It \n", + " herewith resembles the core functionality of the OGC API - Processes, Part 1. \n", + " For details see https://ogcapi.ogc.org/processes/. \n", + " \n", + " You can use shorter command name aliases, e.g., use command name `vr` \n", + " for `validate-request`, or `lp` for `list-processes`. \n", + " \n", + " The tool's exit codes are as follows: \n", + " \n", + " * `0` - normal exit \n", + " * `1` - user errors, argument errors \n", + " * `2` - remote API errors \n", + " * `3` - local network transport errors \n", + " \n", + " If the `--traceback` flag is set, the original Python exception traceback \n", + " will be shown and the exit code will always be `1`. \n", + " Otherwise, only the error message is shown. \n", " \n", "+- Options -------------------------------------------------------------------+\n", "| --version Show version and exit. |\n", @@ -62,6 +76,8 @@ "| configure Configure the client tool. |\n", "| list-processes List available processes. |\n", "| get-process Get process details. |\n", + "| create-request Create an execution request (template) for a given |\n", + "| process. |\n", "| validate-request Validate a process execution request. |\n", "| execute-process Execute a process in asynchronous mode. |\n", "| list-jobs List all jobs. |\n", @@ -74,7 +90,7 @@ } ], "source": [ - " !s2gos-client --help" + "!s2gos-client --help" ] }, { @@ -87,12 +103,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "Client configuration written to C:\\Users\\norma\\.s2gos\\config\n" + "Client configuration written to C:\\Users\\Norman\\.eozilla\\config\n" ] } ], "source": [ - " !s2gos-client configure -s http://127.0.0.1:8008 -u bibo -t 1234" + "!s2gos-client configure -s http://127.0.0.1:8008 -u bibo -t 1234" ] }, { @@ -192,15 +208,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "created: '2025-10-07T14:29:30.827885Z'\n", - "finished: '2025-10-07T14:29:30.828737Z'\n", - "jobID: job_0\n", - "message: Done\n", + "created: '2025-11-10T14:59:01.075900Z'\n", + "jobID: job_2\n", "processID: primes_between\n", - "started: '2025-10-07T14:29:30.828474Z'\n", - "status: successful\n", + "status: accepted\n", "type: process\n", - "updated: '2025-10-07T14:29:30.828715Z'\n", "\n" ] } @@ -220,15 +232,33 @@ "output_type": "stream", "text": [ "jobs:\n", - "- created: '2025-10-07T14:29:30.827885Z'\n", - " finished: '2025-10-07T14:29:30.828737Z'\n", + "- created: '2025-11-10T14:58:35.373594Z'\n", + " finished: '2025-11-10T14:58:35.474882Z'\n", " jobID: job_0\n", + " processID: sleep_a_while\n", + " progress: 0\n", + " started: '2025-11-10T14:58:35.374333Z'\n", + " status: dismissed\n", + " type: process\n", + " updated: '2025-11-10T14:58:35.374437Z'\n", + "- created: '2025-11-10T14:58:35.383115Z'\n", + " finished: '2025-11-10T14:58:35.483986Z'\n", + " jobID: job_1\n", + " processID: sleep_a_while\n", + " progress: 0\n", + " started: '2025-11-10T14:58:35.383514Z'\n", + " status: dismissed\n", + " type: process\n", + " updated: '2025-11-10T14:58:35.383554Z'\n", + "- created: '2025-11-10T14:59:01.075900Z'\n", + " finished: '2025-11-10T14:59:01.076461Z'\n", + " jobID: job_2\n", " message: Done\n", " processID: primes_between\n", - " started: '2025-10-07T14:29:30.828474Z'\n", + " started: '2025-11-10T14:59:01.076390Z'\n", " status: successful\n", " type: process\n", - " updated: '2025-10-07T14:29:30.828715Z'\n", + " updated: '2025-11-10T14:59:01.076449Z'\n", "links:\n", "- href: http://127.0.0.1:8008/jobs\n", " hreflang: en\n", @@ -253,15 +283,15 @@ "name": "stdout", "output_type": "stream", "text": [ - "created: '2025-10-07T14:29:30.827885Z'\n", - "finished: '2025-10-07T14:29:30.828737Z'\n", + "created: '2025-11-10T14:58:35.373594Z'\n", + "finished: '2025-11-10T14:58:35.474882Z'\n", "jobID: job_0\n", - "message: Done\n", - "processID: primes_between\n", - "started: '2025-10-07T14:29:30.828474Z'\n", - "status: successful\n", + "processID: sleep_a_while\n", + "progress: 0\n", + "started: '2025-11-10T14:58:35.374333Z'\n", + "status: dismissed\n", "type: process\n", - "updated: '2025-10-07T14:29:30.828715Z'\n", + "updated: '2025-11-10T14:58:35.374437Z'\n", "\n" ] } @@ -272,34 +302,292 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "id": "fbff4fdfc8434ea7", "metadata": {}, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "return_value:\n", - "- 11\n", - "- 13\n", - "- 17\n", - "- 19\n", - "- 23\n", - "- 29\n", - "- 31\n", - "- 37\n", - "- 41\n", - "- 43\n", - "- 47\n", - "- 53\n", - "- 59\n", - "- 61\n", - "- 67\n", - "- 71\n", - "- 73\n", - "- 79\n", - "\n" + "+--------------------- Traceback (most recent call last) ---------------------+\n", + "| C:\\Users\\Norman\\Projects\\eozilla\\cuiman\\src\\cuiman\\api\\transport\\httpx.py:7 |\n", + "| 8 in _process_response |\n", + "| |\n", + "| 75 ), |\n", + "| 76 ) from e |\n", + "| 77 try: |\n", + "| > 78 response.raise_for_status() |\n", + "| 79 return args.get_response_for_status(response.status_code, |\n", + "| 80 except httpx.HTTPError as e: |\n", + "| 81 raise args.get_exception_for_status( |\n", + "| |\n", + "| +-------------------------------- locals ---------------------------------+ |\n", + "| | args = TransportArgs( | |\n", + "| | path='/jobs/{jobId}/results', | |\n", + "| | method='get', | |\n", + "| | path_params={'jobId': 'job_0'}, | |\n", + "| | query_params={}, | |\n", + "| | request=None, | |\n", + "| | return_types={ | |\n", + "| | '200': | |\n", + "| | }, | |\n", + "| | error_types={ | |\n", + "| | '404': , | |\n", + "| | '500': | |\n", + "| | }, | |\n", + "| | extra_kwargs={} | |\n", + "| | ) | |\n", + "| | response = | |\n", + "| | response_json = { | |\n", + "| | 'type': 'ApiError', | |\n", + "| | 'title': 'Forbidden', | |\n", + "| | 'status': 403, | |\n", + "| | 'detail': \"Job 'job_0' has been cancelled\" | |\n", + "| | } | |\n", + "| | self = | |\n", + "| +-------------------------------------------------------------------------+ |\n", + "| |\n", + "| C:\\Users\\Norman\\Projects\\s2gos-controller\\.pixi\\envs\\default\\Lib\\site-packa |\n", + "| ges\\httpx\\_models.py:829 in raise_for_status |\n", + "| |\n", + "| 826 } |\n", + "| 827 error_type = error_types.get(status_class, \"Invalid status c |\n", + "| 828 message = message.format(self, error_type=error_type) |\n", + "| > 829 raise HTTPStatusError(message, request=request, response=sel |\n", + "| 830 |\n", + "| 831 def json(self, **kwargs: typing.Any) -> typing.Any: |\n", + "| 832 return jsonlib.loads(self.content, **kwargs) |\n", + "| |\n", + "| +-------------------------------- locals ---------------------------------+ |\n", + "| | error_type = 'Client error' | |\n", + "| | error_types = { | |\n", + "| | 1: 'Informational response', | |\n", + "| | 3: 'Redirect response', | |\n", + "| | 4: 'Client error', | |\n", + "| | 5: 'Server error' | |\n", + "| | } | |\n", + "| | message = \"Client error '403 Forbidden' for url | |\n", + "| | 'http://127.0.0.1:8008/jobs/job_0/results'\\n\"+88 | |\n", + "| | request = | |\n", + "| | self = | |\n", + "| | status_class = 4 | |\n", + "| +-------------------------------------------------------------------------+ |\n", + "+-----------------------------------------------------------------------------+\n", + "HTTPStatusError: Client error '403 Forbidden' for url \n", + "'http://127.0.0.1:8008/jobs/job_0/results'\n", + "For more information check: \n", + "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403\n", + "\n", + "The above exception was the direct cause of the following exception:\n", + "\n", + "+--------------------- Traceback (most recent call last) ---------------------+\n", + "| C:\\Users\\Norman\\Projects\\eozilla\\cuiman\\src\\cuiman\\cli\\cli.py:370 in |\n", + "| get_job_results |\n", + "| |\n", + "| 367 from .output import get_renderer, output |\n", + "| 368 |\n", + "| 369 with use_client(ctx, config_file) as client: |\n", + "| > 370 job_results = client.get_job_results(job_id) |\n", + "| 371 output(get_renderer(output_format).render_job_results(job_res |\n", + "| 372 |\n", + "| 373 return t |\n", + "| |\n", + "| +-------------------------------- locals ---------------------------------+ |\n", + "| | client = | |\n", + "| | config_file = None | |\n", + "| | ctx = | |\n", + "| | job_id = 'job_0' | |\n", + "| | output_format = | |\n", + "| +-------------------------------------------------------------------------+ |\n", + "| |\n", + "| C:\\Users\\Norman\\Projects\\eozilla\\cuiman\\src\\cuiman\\api\\client.py:378 in |\n", + "| get_job_results |\n", + "| |\n", + "| 375 - `404`: The requested URI was not found. |\n", + "| 376 - `500`: A server error occurred. |\n", + "| 377 \"\"\" |\n", + "| > 378 return self._transport.call( |\n", + "| 379 TransportArgs( |\n", + "| 380 path=\"/jobs/{jobId}/results\", |\n", + "| 381 method=\"get\", |\n", + "| |\n", + "| +----------------------------- locals -----------------------------+ |\n", + "| | job_id = 'job_0' | |\n", + "| | kwargs = {} | |\n", + "| | self = | |\n", + "| +------------------------------------------------------------------+ |\n", + "| |\n", + "| C:\\Users\\Norman\\Projects\\eozilla\\cuiman\\src\\cuiman\\api\\transport\\httpx.py:3 |\n", + "| 9 in call |\n", + "| |\n", + "| 36 response = self.sync_httpx.request(*args_, **kwargs_) |\n", + "| 37 except httpx.HTTPError as e: |\n", + "| 38 raise TransportError(f\"{e}\") from e |\n", + "| > 39 return self._process_response(args, response) |\n", + "| 40 |\n", + "| 41 async def async_call(self, args: TransportArgs) -> Any: |\n", + "| 42 if self.async_httpx is None: |\n", + "| |\n", + "| +-------------------------------- locals ---------------------------------+ |\n", + "| | args = TransportArgs( | |\n", + "| | path='/jobs/{jobId}/results', | |\n", + "| | method='get', | |\n", + "| | path_params={'jobId': 'job_0'}, | |\n", + "| | query_params={}, | |\n", + "| | request=None, | |\n", + "| | return_types={ | |\n", + "| | '200': | |\n", + "| | }, | |\n", + "| | error_types={ | |\n", + "| | '404': , | |\n", + "| | '500': | |\n", + "| | }, | |\n", + "| | extra_kwargs={} | |\n", + "| | ) | |\n", + "| | args_ = ('GET', 'http://127.0.0.1:8008/jobs/job_0/results') | |\n", + "| | kwargs_ = {'params': {}, 'json': None} | |\n", + "| | response = | |\n", + "| | self = | |\n", + "| +-------------------------------------------------------------------------+ |\n", + "| |\n", + "| C:\\Users\\Norman\\Projects\\eozilla\\cuiman\\src\\cuiman\\api\\transport\\httpx.py:8 |\n", + "| 1 in _process_response |\n", + "| |\n", + "| 78 response.raise_for_status() |\n", + "| 79 return args.get_response_for_status(response.status_code, |\n", + "| 80 except httpx.HTTPError as e: |\n", + "| > 81 raise args.get_exception_for_status( |\n", + "| 82 response.status_code, f\"{e}\", response_json |\n", + "| 83 ) from e |\n", + "| 84 |\n", + "| |\n", + "| +-------------------------------- locals ---------------------------------+ |\n", + "| | args = TransportArgs( | |\n", + "| | path='/jobs/{jobId}/results', | |\n", + "| | method='get', | |\n", + "| | path_params={'jobId': 'job_0'}, | |\n", + "| | query_params={}, | |\n", + "| | request=None, | |\n", + "| | return_types={ | |\n", + "| | '200': | |\n", + "| | }, | |\n", + "| | error_types={ | |\n", + "| | '404': , | |\n", + "| | '500': | |\n", + "| | }, | |\n", + "| | extra_kwargs={} | |\n", + "| | ) | |\n", + "| | response = | |\n", + "| | response_json = { | |\n", + "| | 'type': 'ApiError', | |\n", + "| | 'title': 'Forbidden', | |\n", + "| | 'status': 403, | |\n", + "| | 'detail': \"Job 'job_0' has been cancelled\" | |\n", + "| | } | |\n", + "| | self = | |\n", + "| +-------------------------------------------------------------------------+ |\n", + "+-----------------------------------------------------------------------------+\n", + "ClientError: Client error '403 Forbidden' for url \n", + "'http://127.0.0.1:8008/jobs/job_0/results'\n", + "For more information check: \n", + "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403 (status 403)\n", + "\n", + "During handling of the above exception, another exception occurred:\n", + "\n", + "+--------------------- Traceback (most recent call last) ---------------------+\n", + "| C:\\Users\\Norman\\Projects\\eozilla\\cuiman\\src\\cuiman\\cli\\cli.py:369 in |\n", + "| get_job_results |\n", + "| |\n", + "| 366 from .client import use_client |\n", + "| 367 from .output import get_renderer, output |\n", + "| 368 |\n", + "| > 369 with use_client(ctx, config_file) as client: |\n", + "| 370 job_results = client.get_job_results(job_id) |\n", + "| 371 output(get_renderer(output_format).render_job_results(job_res |\n", + "| 372 |\n", + "| |\n", + "| +-------------------------------- locals ---------------------------------+ |\n", + "| | client = | |\n", + "| | config_file = None | |\n", + "| | ctx = | |\n", + "| | job_id = 'job_0' | |\n", + "| | output_format = | |\n", + "| +-------------------------------------------------------------------------+ |\n", + "| |\n", + "| C:\\Users\\Norman\\Projects\\eozilla\\cuiman\\src\\cuiman\\cli\\client.py:61 in |\n", + "| __exit__ |\n", + "| |\n", + "| 58 if api_error.traceback and show_traceback: |\n", + "| 59 message_lines.append(\" traceback:\") |\n", + "| 60 message_lines.extend(api_error.traceback) |\n", + "| > 61 typer.echo(\"\\n\".join(message_lines)) |\n", + "| 62 if not show_traceback: |\n", + "| 63 raise typer.Exit(code=2) |\n", + "| 64 elif isinstance(exc_value, TransportError): |\n", + "| |\n", + "| +-------------------------------- locals ---------------------------------+ |\n", + "| | api_error = ApiError( | |\n", + "| | type='ApiError', | |\n", + "| | title='Forbidden', | |\n", + "| | status=403, | |\n", + "| | detail=\"Job 'job_0' has been cancelled\", | |\n", + "| | instance=None, | |\n", + "| | traceback=None | |\n", + "| | ) | |\n", + "| | client_error = ClientError(\"Client error '403 Forbidden' for url | |\n", + "| | 'http://127.0.0.1:8008/jobs/job_0/results'\\nFor more | |\n", + "| | information check: | |\n", + "| | https://developer.mozilla.org/en-US/docs/Web/HTTP/Sta… | |\n", + "| | (status 403)\") | |\n", + "| | exc_tb = | |\n", + "| | exc_value = ClientError(\"Client error '403 Forbidden' for url | |\n", + "| | 'http://127.0.0.1:8008/jobs/job_0/results'\\nFor more | |\n", + "| | information check: | |\n", + "| | https://developer.mozilla.org/en-US/docs/Web/HTTP/Sta… | |\n", + "| | (status 403)\") | |\n", + "| | message_lines = [ | |\n", + "| | \"\\u274c Error: Client error '403 Forbidden' for url | |\n", + "| | 'http://127.0.0.1:8008/jobs/job_0/\"+110, | |\n", + "| | 'Server-side error details:', | |\n", + "| | ' title: Forbidden', | |\n", + "| | ' status: 403', | |\n", + "| | ' type: ApiError', | |\n", + "| | \" detail: Job 'job_0' has been cancelled\" | |\n", + "| | ] | |\n", + "| | self = | |\n", + "| | show_traceback = False | |\n", + "| +-------------------------------------------------------------------------+ |\n", + "| |\n", + "| C:\\Users\\Norman\\Projects\\s2gos-controller\\.pixi\\envs\\default\\Lib\\site-packa |\n", + "| ges\\click\\utils.py:321 in echo |\n", + "| |\n", + "| C:\\Users\\Norman\\Projects\\s2gos-controller\\.pixi\\envs\\default\\Lib\\encodings\\ |\n", + "| cp1252.py:19 in encode |\n", + "| |\n", + "| 16 |\n", + "| 17 class IncrementalEncoder(codecs.IncrementalEncoder): |\n", + "| 18 def encode(self, input, final=False): |\n", + "| > 19 return codecs.charmap_encode(input,self.errors,encoding_table |\n", + "| 20 |\n", + "| 21 class IncrementalDecoder(codecs.IncrementalDecoder): |\n", + "| 22 def decode(self, input, final=False): |\n", + "| |\n", + "| +-------------------------------- locals ---------------------------------+ |\n", + "| | final = False | |\n", + "| | input = \"\\u274c Error: Client error '403 Forbidden' for url | |\n", + "| | 'http://127.0.0.1:8008/jobs/job_0/\"+239 | |\n", + "| | self = | |\n", + "| +-------------------------------------------------------------------------+ |\n", + "+-----------------------------------------------------------------------------+\n", + "UnicodeEncodeError: 'charmap' codec can't encode character '\\u274c' in position\n", + "0: character maps to \n" ] } ], diff --git a/notebooks/client-gui.ipynb b/notebooks/client-gui.ipynb index 10246bb..5a0115a 100644 --- a/notebooks/client-gui.ipynb +++ b/notebooks/client-gui.ipynb @@ -20,7 +20,7 @@ "with a test configuration:\n", "\n", "```bash\n", - "s2gos-server run -- s2gos_server.services.local.testing:service\n", + "s2gos-server run -- wraptile.services.local.testing:service\n", "```" ] }, @@ -601,12 +601,12 @@ "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ - "
\n", - "
\n", + "
\n", + "
\n", "
\n", "" ], "text/plain": [ - "JobsPanel(name='JobsPanel00292')" + "JobsPanel(name='JobsPanel00293')" ] }, - "execution_count": 8, + "execution_count": 7, "metadata": { "application/vnd.holoviews_exec.v0+json": { - "id": "64ad79f6-0cb2-45fb-9c2f-dc44ef57454d" + "id": "0037bd36-cb7d-47d3-be6a-3dc0c7d1746f" } }, "output_type": "execute_result" @@ -1199,12 +1199,12 @@ "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ - "
\n", - "
\n", + "
\n", + "
\n", "
\n", "" ], "text/plain": [ - "JobInfoPanel(client_error=None, job_info=JobInfo(processID='simulate_scene', type=, jobID='job_0', status=, message=None, created=datetime.datetime(2025, 10, 7, 14, 25, 37, 255395, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 10, 7, 14, 25, 37, 256061, tzinfo=TzInfo(UTC)), finished=datetime.datetime(2025, 10, 7, 14, 25, 40, 838015, tzinfo=TzInfo(UTC)), updated=None, progress=None, links=None, traceback=None), name='JobInfoPanel00534')" + "JobInfoPanel(client_error=None, job_info=JobInfo(processID='simulate_scene', type=, jobID='job_3', status=, message=None, created=datetime.datetime(2025, 11, 10, 15, 0, 17, 657120, tzinfo=TzInfo(UTC)), started=datetime.datetime(2025, 11, 10, 15, 0, 17, 657646, tzinfo=TzInfo(UTC)), finished=datetime.datetime(2025, 11, 10, 15, 0, 19, 536983, tzinfo=TzInfo(UTC)), updated=None, progress=None, links=None, traceback=None), name='JobInfoPanel00371')" ] }, "execution_count": 9, "metadata": { "application/vnd.holoviews_exec.v0+json": { - "id": "c31c7bb9-dbf3-4fd3-886a-6db516b3223c" + "id": "7e8c262c-a2ef-4b0d-b840-abc9dbf5c519" } }, "output_type": "execute_result" } ], "source": [ - "client.show_job(\"job_0\")" + "client.show_job(\"job_3\")" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "133234e0-e393-4384-972c-de5cbaa3d91c", "metadata": {}, "outputs": [ @@ -1297,7 +1297,7 @@ "data": { "application/json": { "return_value": { - "href": "file:///C:/Users/norma/Projects/s2gos-controller/test.zarr", + "href": "file:///C:/Users/Norman/Projects/s2gos-controller/notebooks/test.zarr", "hreflang": null, "rel": null, "title": null, @@ -1305,14 +1305,14 @@ } }, "text/plain": [ - "{'return_value': {'href': 'file:///C:/Users/norma/Projects/s2gos-controller/test.zarr',\n", + "{'return_value': {'href': 'file:///C:/Users/Norman/Projects/s2gos-controller/notebooks/test.zarr',\n", " 'rel': None,\n", " 'type': 'application/zarr',\n", " 'hreflang': None,\n", " 'title': None}}" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": { "application/json": { "root": "Results:" @@ -1327,7 +1327,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "cea797e0-9977-4727-98df-b4d6a3cccf65", "metadata": {}, "outputs": [ @@ -1777,25 +1777,29 @@ " filter: drop-shadow(1px 1px 5px var(--xr-font-color2));\n", " stroke-width: 0.8px;\n", "}\n", - "
<xarray.Dataset> Size: 388kB\n",
-       "Dimensions:  (time: 16, lat: 24, lon: 42)\n",
+       "
<xarray.Dataset> Size: 538kB\n",
+       "Dimensions:  (time: 16, lat: 25, lon: 56)\n",
        "Coordinates:\n",
-       "  * lon      (lon) float64 336B -14.26 -13.76 -13.26 ... 5.327 5.829 6.331\n",
-       "  * lat      (lat) float64 192B 34.42 34.92 35.42 35.92 ... 44.95 45.45 45.95\n",
+       "  * lon      (lon) float64 448B -4.206 -3.704 -3.202 ... 22.41 22.92 23.42\n",
+       "  * lat      (lat) float64 200B 44.55 45.06 45.56 46.07 ... 55.66 56.16 56.67\n",
        "  * time     (time) datetime64[ns] 128B 2025-01-01 2025-01-02 ... 2025-01-16\n",
        "Data variables:\n",
-       "    a        (time, lat, lon) float64 129kB ...\n",
-       "    c        (time, lat, lon) float64 129kB ...\n",
-       "    b        (time, lat, lon) float64 129kB ...
  • " ], "text/plain": [ - " Size: 388kB\n", - "Dimensions: (time: 16, lat: 24, lon: 42)\n", + " Size: 538kB\n", + "Dimensions: (time: 16, lat: 25, lon: 56)\n", "Coordinates:\n", - " * lon (lon) float64 336B -14.26 -13.76 -13.26 ... 5.327 5.829 6.331\n", - " * lat (lat) float64 192B 34.42 34.92 35.42 35.92 ... 44.95 45.45 45.95\n", + " * lon (lon) float64 448B -4.206 -3.704 -3.202 ... 22.41 22.92 23.42\n", + " * lat (lat) float64 200B 44.55 45.06 45.56 46.07 ... 55.66 56.16 56.67\n", " * time (time) datetime64[ns] 128B 2025-01-01 2025-01-02 ... 2025-01-16\n", "Data variables:\n", - " a (time, lat, lon) float64 129kB ...\n", - " c (time, lat, lon) float64 129kB ...\n", - " b (time, lat, lon) float64 129kB ..." + " a (time, lat, lon) float64 179kB ...\n", + " c (time, lat, lon) float64 179kB ...\n", + " b (time, lat, lon) float64 179kB ..." ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } diff --git a/pixi.lock b/pixi.lock index 3bece08..e30a132 100644 --- a/pixi.lock +++ b/pixi.lock @@ -378,9 +378,7 @@ environments: - pypi: ../eozilla/gavicore - pypi: ../eozilla/procodile - pypi: ../eozilla/wraptile - - pypi: ./s2gos-app-ex - pypi: ./s2gos-client - - pypi: ./s2gos-common - pypi: ./s2gos-server osx-64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda @@ -742,9 +740,7 @@ environments: - pypi: ../eozilla/gavicore - pypi: ../eozilla/procodile - pypi: ../eozilla/wraptile - - pypi: ./s2gos-app-ex - pypi: ./s2gos-client - - pypi: ./s2gos-common - pypi: ./s2gos-server win-64: - conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda @@ -1096,9 +1092,7 @@ environments: - pypi: ../eozilla/gavicore - pypi: ../eozilla/procodile - pypi: ../eozilla/wraptile - - pypi: ./s2gos-app-ex - pypi: ./s2gos-client - - pypi: ./s2gos-common - pypi: ./s2gos-server packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -1179,8 +1173,8 @@ packages: requires_python: ~=3.9 - pypi: ../eozilla/appligator name: appligator - version: 0.0.8.dev0 - sha256: 6a4c923c2c6a478fd7d6efd2bf686acef4036328ec7697125e07fc3b77beff23 + version: 0.0.8 + sha256: 02c0f3d145b3b7cec7bcc0e4efb1185ffeb9c6e5491e0603e2e4262c74e9f620 requires_dist: - pydantic - pyyaml @@ -2634,8 +2628,8 @@ packages: timestamp: 1749539269244 - pypi: ../eozilla/cuiman name: cuiman - version: 0.0.8.dev0 - sha256: c2d45f9ba8268315d501434e507801678cc9038cebf78496e83a08a9faeca910 + version: 0.0.8 + sha256: 871aaa2a3816d3e4ff13bdf7b7a8e1350334cc4c9c31b24e4d1e9df2831e80f4 requires_dist: - click - panel @@ -3051,8 +3045,8 @@ packages: timestamp: 1748101667956 - pypi: ../eozilla/gavicore name: gavicore - version: 0.0.8.dev0 - sha256: 2f554fb6cb2530441f8a6ef8aa0c639ad7b4f8141ee99e9bec3eb3eb8a417dec + version: 0.0.8 + sha256: 488145ac6c86f4b19f5169523deab4ab235b1edb34422b14242df95c6e9e91e6 requires_dist: - click - pydantic @@ -7755,8 +7749,8 @@ packages: timestamp: 1747339794916 - pypi: ../eozilla/procodile name: procodile - version: 0.0.8.dev0 - sha256: bcfc4f38f4679048eb6b9d2896f5780674d18ca03d90b7a8726f300995953996 + version: 0.0.8 + sha256: 761ceddd0d3ac3b5717e1fa18c73ac7f949c2fd57e621dde38e721aea31d589b requires_dist: - pydantic - pyyaml @@ -8786,12 +8780,6 @@ packages: - pkg:pypi/ruff?source=hash-mapping size: 8291919 timestamp: 1750189141795 -- pypi: ./s2gos-app-ex - name: s2gos-app-ex - version: 0.0.0 - sha256: fe053f016670ef03d9da693a3bfc9b912ad8dcb5dfe429ca625ffd59a768cc7d - requires_python: '>=3.10' - editable: true - pypi: ./s2gos-client name: s2gos-client version: 0.0.6.dev0 @@ -8807,15 +8795,6 @@ packages: - gavicore requires_python: '>=3.10' editable: true -- pypi: ./s2gos-common - name: s2gos-common - version: 0.0.6.dev0 - sha256: 29bba461bdf0b50cf903ce0ef2cc318161518bd025e70f97d98203eb1fd92a88 - requires_dist: - - pydantic - - typer - requires_python: '>=3.10' - editable: true - pypi: ./s2gos-server name: s2gos-server version: 0.0.6.dev0 @@ -9885,8 +9864,8 @@ packages: timestamp: 1736870265811 - pypi: ../eozilla/wraptile name: wraptile - version: 0.0.8.dev0 - sha256: 18aebc189b21453308d28597524a9585b3d999ab3fa52d90fe8a6e3665ced6bc + version: 0.0.8 + sha256: 436c794e970c9aebbbbe51a9454f8c7c395a8df52cebed220663569b8b682bf7 requires_dist: - fastapi - pydantic diff --git a/pyproject.toml b/pyproject.toml index cb5169f..a1cff29 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "s2gos-controller" -version = "0.0.6.dev0" -description = "S2GOS control layer comprising a server and client" +version = "0.1.0.dev0" +description = "S2GOS control layer comprising a gateway server and client" requires-python = ">=3.10" [tool.pixi.workspace] @@ -63,9 +63,7 @@ pymdown-extensions = "*" # or even better "[tool.pixi.workspaces]". # See https://github.com/prefix-dev/pixi/issues/1417. s2gos-client = { path = "s2gos-client", editable = true } -s2gos-common = { path = "s2gos-common", editable = true } s2gos-server = { path = "s2gos-server", editable = true } -s2gos-app-ex = { path = "s2gos-app-ex", editable = true } # TODO: once stable, move into project (conda-forge) dependencies appligator = { path = "../eozilla/appligator", editable = true } cuiman = { path = "../eozilla/cuiman", editable = true } @@ -83,7 +81,7 @@ mkdocs-mermaid2-plugin = "*" skip = [".idea", ".github", ".pixi", "htmlcov", "site"] profile = "black" line_length = 88 -known_first_party = ["s2gos_common", "s2gos_client", "s2gos_server", "s2gos_app_ex"] +known_first_party = ["s2gos_client", "s2gos_server"] [tool.black] line-length = 88 @@ -91,10 +89,8 @@ line-length = 88 [tool.ruff] include = [ "notebooks/**/*.py", - "s2gos-common/src/**/*.py", - "s2gos-server/src/**/*.py", "s2gos-client/src/**/*.py", - "s2gos-app-ex/src/**/*.py", + "s2gos-server/src/**/*.py", "tools/**/*.py", ] @@ -105,51 +101,39 @@ per-file-ignores = { "*.ipynb" = ["E402"] } select = ["I", "F", "E"] [tool.coverage.report] -omit = [ - "s2gos-app-ex/src/s2gos_app_ex/**/*", - "s2gos-client/src/s2gos_client/gui/**/*", - "s2gos-server/src/s2gos_server/services/airflow/**/*", -] +omit = [] [tool.mypy] python_version = "3.10" check_untyped_defs = true disable_error_code = ["valid-type", "import-untyped"] exclude = [ - "s2gos-airflow", - "s2gos-app-ex/src/test", "s2gos-client/src/test", - "s2gos-common/src/test", "s2gos-server/src/test", "tools", ] -[[tool.mypy.overrides]] -module = "s2gos_common.models" -disable_error_code = ["valid-type"] ########################## Tasks ############################### # pixi run test [tool.pixi.tasks.test] -depends-on = ["test-common", "test-server", "test-client"] +depends-on = ["test-client", "test-server"] -[tool.pixi.tasks.test-common] -cmd = "pytest s2gos-common/src/tests" +[tool.pixi.tasks.test-client] +cmd = "pytest s2gos-client/tests" [tool.pixi.tasks.test-server] -cmd = "pytest s2gos-server/src/tests" +cmd = "pytest s2gos-server/tests" -[tool.pixi.tasks.test-client] -cmd = "pytest s2gos-client/src/tests" # pixi run coverage / coverage-ci [tool.pixi.tasks.coverage] -depends-on = ["cov-common", "cov-server", "cov-client", "cov-report-html"] +depends-on = ["cov-client", "cov-server", "cov-report-html"] [tool.pixi.tasks.coverage-ci] -depends-on = ["cov-common", "cov-server", "cov-client", "cov-report-xml"] +depends-on = ["cov-client", "cov-server", "cov-report-xml"] [tool.pixi.tasks.cov-report-html] cmd = "coverage html -d .cov-report && coverage report" @@ -157,52 +141,31 @@ cmd = "coverage html -d .cov-report && coverage report" [tool.pixi.tasks.cov-report-xml] cmd = "coverage xml -o coverage.xml && coverage report" -[tool.pixi.tasks.cov-common] -cmd = "pytest --cov s2gos-common/src/s2gos_common --cov-report= --cov-append s2gos-common/src/tests" +[tool.pixi.tasks.cov-client] +cmd = "pytest --cov s2gos-client/src/s2gos_client --cov-report= --cov-append s2gos-client/tests" [tool.pixi.tasks.cov-server] -cmd = "pytest --cov s2gos-server/src/s2gos_server --cov-report= --cov-append s2gos-server/src/tests" - -[tool.pixi.tasks.cov-client] -cmd = "pytest --cov s2gos-client/src/s2gos_client --cov-report= --cov-append s2gos-client/src/tests" +cmd = "pytest --cov s2gos-server/src/s2gos_server --cov-report= --cov-append s2gos-server/tests" # pixi run check [tool.pixi.tasks.check] -depends-on = ["check-common", "check-server", "check-client", "typecheck"] +depends-on = ["check-client", "check-server", "typecheck"] -[tool.pixi.tasks.check-common] -cmd = "ruff check s2gos-common/src" +[tool.pixi.tasks.check-client] +cmd = "ruff check s2gos-client/src" [tool.pixi.tasks.check-server] cmd = "ruff check s2gos-server/src" -[tool.pixi.tasks.check-client] -cmd = "ruff check s2gos-client/src" - [tool.pixi.tasks.typecheck] cmd = "mypy ." # pixi run generate -[tool.pixi.tasks.generate] -depends-on = ["gen-models", "gen-server", "gen-client", "gen-client-docs"] - -[tool.pixi.tasks.gen-models] -cmd = "python -m tools.gen_models" - -[tool.pixi.tasks.gen-server] -cmd = "python -m tools.gen_server" - -[tool.pixi.tasks.gen-client] -cmd = "python -m tools.gen_client" - [tool.pixi.tasks.gen-client-docs] cmd = "python -m tools.gen_client_docs" -[tool.pixi.tasks.gen-dags] -cmd = "python -m tools.gen_dags" - # pixi run sync-versions [tool.pixi.tasks.sync-versions] diff --git a/s2gos-airflow/.gitignore b/s2gos-airflow/.gitignore deleted file mode 100644 index d568468..0000000 --- a/s2gos-airflow/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.pixi -.venv/ -.airflow/ -.env -__pycache__/ diff --git a/s2gos-airflow/LICENSE b/s2gos-airflow/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/s2gos-airflow/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/s2gos-airflow/README.md b/s2gos-airflow/README.md deleted file mode 100644 index 1bdcfca..0000000 --- a/s2gos-airflow/README.md +++ /dev/null @@ -1,80 +0,0 @@ -# DTE-S2GOS controller Airflow - -Airflow DAGs for the ESA DTE-S2GOS synthetic scene generator service - -## Setup - -This setup creates a minimal local Airflow development environment -using [pixi](https://pixi.sh). -All packages are currently installed from PyPI as this is the only reliable -way to install Airflow 3.0. -Also, all Airflow configuration is local, namely in `./.airflow`, -see `AIRFLOW_HOME` variable in `pyproject.toml`. - -Windows users: this setup has been successfully tested with -[WSL2](https://learn.microsoft.com/de-de/windows/wsl/) 2.4.11 -using Ubuntu 24.04.2 LTS. Airflow has no official Windows support. - -```bash -cd projects -git clone https://github.com/s2gos-dev/s2gos-controller.git -cd s2gos-controller/s2gos-airflow -``` - -```bash -pixi install -pixi run install-airflow -``` - -## Code - -```bash -pixi shell -``` - -Given that [VS Code](https://code.visualstudio.com/download) is installed - -```bash -code . -``` - -WSL users, see [VS Code with WSL](https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-vscode). - -## Develop - -```bash -pixi run format -pixi run test -pixi run check -pixi run typecheck -``` - -## Generate DAGs - -```bash -pixi run gen-dags -``` - -## Run Airflow - -Run all Airflow services at once: - -```bash -pixi run airflow standalone -``` - -Or run each Airflow service individually: - -```bash -pixi run airflow db migrate -pixi run airflow dag-processor -pixi run airflow scheduler -pixi run airflow api-server -``` - -The Airflow API Server runs at URL http://localhost:8080. To find login credentials, -search for the log entry `Simple auth manager | Password for user 'admin'`. - -If you forgot the username/password, you can look it up in -`.airflow/simple_auth_manager_passwords.json.generated`. -You can safely delete the file to force creation of a new password. diff --git a/s2gos-airflow/dags/primes_between.py b/s2gos-airflow/dags/primes_between.py deleted file mode 100644 index 9a46b24..0000000 --- a/s2gos-airflow/dags/primes_between.py +++ /dev/null @@ -1,28 +0,0 @@ -# generated by gen_dags.py: -# filename: primes_between.py: -# timestamp: 2025-07-24T15:06:10.731450 - -from airflow.sdk import Param, dag, task - -from s2gos_server.services.local.testing import primes_between - - -@dag( - "primes_between", - dag_display_name="Prime Processor", - description="Returns the list of prime numbers between a `min_val` and `max_val`. ", - params={ - "min_val": Param(default=0, type="integer", title="Min Val", minimum=0.0), - "max_val": Param(default=100, type="integer", title="Max Val", maximum=100.0), - }, - is_paused_upon_creation=False, -) -def primes_between_dag(): - @task(multiple_outputs=False) - def primes_between_task(params): - return primes_between(**params) - - task_instance = primes_between_task() # noqa: F841 - - -primes_between_dag() diff --git a/s2gos-airflow/dags/return_base_model.py b/s2gos-airflow/dags/return_base_model.py deleted file mode 100644 index d1d2332..0000000 --- a/s2gos-airflow/dags/return_base_model.py +++ /dev/null @@ -1,32 +0,0 @@ -# generated by gen_dags.py: -# filename: return_base_model.py: -# timestamp: 2025-07-24T15:06:11.326255 - -from airflow.sdk import Param, dag, task - -from s2gos_server.services.local.testing import return_base_model - - -@dag( - "return_base_model", - dag_display_name="BaseModel Test", - description=None, - params={ - "scene_spec": Param( - type="object", - title="SceneSpec", - properties={"threshold": {"title": "Threshold", "type": "number"}}, - required=["threshold"], - ), - }, - is_paused_upon_creation=False, -) -def return_base_model_dag(): - @task(multiple_outputs=False) - def return_base_model_task(params): - return return_base_model(**params) - - task_instance = return_base_model_task() # noqa: F841 - - -return_base_model_dag() diff --git a/s2gos-airflow/dags/simulate_scene.py b/s2gos-airflow/dags/simulate_scene.py deleted file mode 100644 index 2cb35a9..0000000 --- a/s2gos-airflow/dags/simulate_scene.py +++ /dev/null @@ -1,70 +0,0 @@ -# generated by gen_dags.py: -# filename: simulate_scene.py: -# timestamp: 2025-07-24T15:06:11.032238 - -from airflow.sdk import Param, dag, task - -from s2gos_server.services.local.testing import simulate_scene - - -@dag( - "simulate_scene", - dag_display_name="Generate scene for testing", - description="Simulate a set scene images slices for testing. Creates an xarray dataset with `periodicity` time slices and writes it as Zarr into a temporary location. Requires installed `dask`, `xarray`, and `zarr` packages.", - params={ - "var_names": Param( - default="a, b, c", - type="string", - title="Variable names", - description="Comma-separated list of variable names.", - ), - "bbox": Param( - default=[-180, -90, 180, 90], - type="array", - title="Bounding box", - description="Bounding box in geographical coordinates.", - format="bbox", - items={"type": "number"}, - maxItems=4, - minItems=4, - ), - "resolution": Param( - default=0.5, - type="number", - title="Spatial resolution", - description="Spatial resolution in degree.", - maximum=1.0, - minimum=0.01, - ), - "start_date": Param( - default="2025-01-01", type="string", title="Start date", format="date" - ), - "end_date": Param( - default="2025-02-01", type="string", title="End date", format="date" - ), - "periodicity": Param( - default=1, - type="integer", - title="Periodicity", - description="Size of time steps in days.", - maximum=10.0, - minimum=1.0, - ), - "output_path": Param( - type="string", - title="Output path", - description="Local output path or URI.", - nullable=True, - ), - }, - is_paused_upon_creation=False, -) -def simulate_scene_dag(): - @task(multiple_outputs=False) - def simulate_scene_task(params): - return simulate_scene(**params) - - task_instance = simulate_scene_task() # noqa: F841 - - -simulate_scene_dag() diff --git a/s2gos-airflow/dags/sleep_a_while.py b/s2gos-airflow/dags/sleep_a_while.py deleted file mode 100644 index 3062bda..0000000 --- a/s2gos-airflow/dags/sleep_a_while.py +++ /dev/null @@ -1,28 +0,0 @@ -# generated by gen_dags.py: -# filename: sleep_a_while.py: -# timestamp: 2025-07-24T15:06:10.425749 - -from airflow.sdk import Param, dag, task - -from s2gos_server.services.local.testing import sleep_a_while - - -@dag( - "sleep_a_while", - dag_display_name="Sleep Processor", - description="Sleeps for `duration` seconds. Fails on purpose if `fail` is `True`. Returns the effective amount of sleep in seconds.", - params={ - "duration": Param(default=10.0, type="number", title="Duration"), - "fail": Param(default=False, type="boolean", title="Fail"), - }, - is_paused_upon_creation=False, -) -def sleep_a_while_dag(): - @task(multiple_outputs=False) - def sleep_a_while_task(params): - return sleep_a_while(**params) - - task_instance = sleep_a_while_task() # noqa: F841 - - -sleep_a_while_dag() diff --git a/s2gos-airflow/notebooks/airflow-client-test.ipynb b/s2gos-airflow/notebooks/airflow-client-test.ipynb deleted file mode 100644 index ea480ed..0000000 --- a/s2gos-airflow/notebooks/airflow-client-test.ipynb +++ /dev/null @@ -1,178 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 4, - "id": "3f75681f-bc08-491e-81f6-5d1dcc88b7f3", - "metadata": {}, - "outputs": [ - { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'airflow_client'", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mModuleNotFoundError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 4\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;28;01mimport\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mos\u001b[39;00m\n\u001b[32m 2\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mpprint\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m pprint\n\u001b[32m----> \u001b[39m\u001b[32m4\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mairflow_client\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mconfig\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m ApiClient, Configuration\n\u001b[32m 5\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mairflow_client\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mclient\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mapi\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m dag_api, auth_api\n\u001b[32m 6\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mairflow_client\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mclient\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mmodel\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mlogin_form\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m LoginForm\n", - "\u001b[31mModuleNotFoundError\u001b[39m: No module named 'airflow_client'" - ] - } - ], - "source": [ - "import os\n", - "from pprint import pprint\n", - "\n", - "from airflow_client.config import ApiClient, Configuration\n", - "from airflow_client.client.api import dag_api, auth_api\n", - "from airflow_client.client.model.login_form import LoginForm" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "4d26cca6-f01e-4e9b-ac9c-77ba7abe823a", - "metadata": {}, - "outputs": [], - "source": [ - "# --- Configuration ---\n", - "AIRFLOW_API_BASE_URL = os.getenv(\"AIRFLOW_API_BASE_URL\", \"http://localhost:8080/api/v2\")\n", - "AIRFLOW_USERNAME = os.getenv(\"AIRFLOW_USERNAME\", \"admin\")\n", - "AIRFLOW_PASSWORD = os.getenv(\"AIRFLOW_PASSWORD\", \"gWD2q2pFt9k7fZUF\")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "7a1c3d7f-09ec-4f24-bdf9-6f5d178e631e", - "metadata": {}, - "outputs": [], - "source": [ - "# --- Authentication (JWT Token) ---\n", - "def get_airflow_jwt_token(host, username, password):\n", - " # This assumes the /auth/token endpoint is at the base URL, not /api/v2\n", - " # Adjust if your setup places it differently.\n", - " config = Configuration(host=host)\n", - " with ApiClient(config) as api_client:\n", - " auth_instance = auth_api.AuthApi(api_client)\n", - " login_form = LoginForm(username=username, password=password)\n", - " try:\n", - " auth_response = auth_instance.login(login_form=login_form)\n", - " return auth_response.access_token\n", - " except Exception as e:\n", - " print(f\"Error obtaining JWT token: {e}\")\n", - " raise" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "3bb109fb-02b5-421c-a4ad-d44a24bb6958", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Could not get JWT token. Ensure Airflow is running and credentials are correct. Error: name 'Configuration' is not defined\n" - ] - } - ], - "source": [ - "try:\n", - " # Get the token from the base URL (without /api/v2)\n", - " jwt_token = get_airflow_jwt_token(AIRFLOW_API_BASE_URL.replace(\"/api/v2\", \"\"), AIRFLOW_USERNAME, AIRFLOW_PASSWORD)\n", - " configuration = Configuration(\n", - " host=AIRFLOW_API_BASE_URL,\n", - " access_token=jwt_token\n", - " )\n", - "except Exception as e:\n", - " print(f\"Could not get JWT token. Ensure Airflow is running and credentials are correct. Error: {e}\")\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e59e1f3-10a4-4a00-946a-294df378ab4c", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "# --- Airflow API Interactions ---\n", - "with ApiClient(configuration) as api_client:\n", - " # Create an instance of the DAGApi\n", - " dags_api_instance = dag_api.DAGApi(api_client)\n", - "\n", - " # --- 1. Get all DAGs ---\n", - " print(\"\\n--- Getting all active DAGs ---\")\n", - " try:\n", - " # You can use parameters like 'only_active=True' to filter results\n", - " # 'limit' and 'offset' for pagination if you have many DAGs\n", - " list_dags_response = dags_api_instance.get_dags(only_active=True)\n", - " \n", - " if list_dags_response and list_dags_response.dags:\n", - " print(f\"Found {len(list_dags_response.dags)} active DAGs:\")\n", - " for dag in list_dags_response.dags:\n", - " print(f\" - DAG ID: {dag.dag_id}, Is Paused: {dag.is_paused}, File Location: {dag.fileloc}\")\n", - " # For a more complete view of what's available:\n", - " # pprint(dag.to_dict()) # Uncomment to see full dictionary for each DAG\n", - " else:\n", - " print(\"No active DAGs found.\")\n", - "\n", - " except Exception as e:\n", - " print(f\"Error getting all DAGs: {e}\")\n", - "\n", - " # --- 2. Get details for a given DAG ---\n", - " # Replace with a DAG_ID that exists in your Airflow instance\n", - " target_dag_id = \"example_bash_operator\" # Or one of the IDs from the list above\n", - "\n", - " print(f\"\\n--- Getting details for DAG: '{target_dag_id}' ---\")\n", - " try:\n", - " dag_details = dags_api_instance.get_dag(dag_id=target_dag_id)\n", - " \n", - " print(f\"Details for DAG ID: {dag_details.dag_id}\")\n", - " print(f\" Description: {dag_details.description}\")\n", - " print(f\" File Location: {dag_details.fileloc}\")\n", - " print(f\" Is Paused: {dag_details.is_paused}\")\n", - " print(f\" Schedule Interval: {dag_details.schedule_interval.to_dict() if dag_details.schedule_interval else 'None'}\")\n", - " \n", - " # Accessing parameters (new in Airflow 3.x - if defined in the DAG)\n", - " if dag_details.params:\n", - " print(\" Defined Parameters (params):\")\n", - " for param_key, param_value in dag_details.params.items():\n", - " print(f\" - {param_key}:\")\n", - " # 'param_value' will be an instance of 'Param' model\n", - " print(f\" Type: {param_value.type}, Default: {param_value.default}, Description: {param_value.description}\")\n", - " else:\n", - " print(\" No parameters (params) defined for this DAG.\")\n", - "\n", - " print(\"\\nFull DAG details (as dictionary):\")\n", - " pprint(dag_details.to_dict())\n", - "\n", - " except Exception as e:\n", - " print(f\"Error getting details for DAG '{target_dag_id}': {e}\")\n", - " print(\"Please ensure the DAG ID is correct and it exists in your Airflow instance.\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.13.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/s2gos-airflow/notebooks/airflow-setup.ipynb b/s2gos-airflow/notebooks/airflow-setup.ipynb deleted file mode 100644 index 51235ec..0000000 --- a/s2gos-airflow/notebooks/airflow-setup.ipynb +++ /dev/null @@ -1,1455 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "08ee897d-8b1b-40b3-8555-deda50f81de7", - "metadata": {}, - "source": [ - "From https://airflow.apache.org/docs/apache-airflow/stable/security/api.html:\n", - "\n", - "Get API access token (JWT):\n", - "```\n", - "curl -X POST ${ENDPOINT_URL}/auth/token \\\n", - " -H \"Content-Type: application/json\" \\\n", - " -d '{\n", - " \"username\": \"your-username\",\n", - " \"password\": \"your-password\"\n", - " }'\n", - "```\n", - "\n", - "Test API call:\n", - "```\n", - "curl -X GET ${ENDPOINT_URL}/api/v2/dags \\\n", - " -H \"Authorization: Bearer \"\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "3b8fa98d-4b61-473b-9e91-b3a4b226419a", - "metadata": {}, - "outputs": [], - "source": [ - "import requests" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "ca7fd77a-db95-44ec-a545-2404092b3a48", - "metadata": {}, - "outputs": [], - "source": [ - "ENDPOINT_URL = \"http://localhost:8080\"" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "cbd20d64-5884-48ac-8673-02b835697ad2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "response = requests.post(\n", - " f\"{ENDPOINT_URL}/auth/token\", \n", - " headers={\"Content-Type\": \"application/json\"},\n", - " json={\"username\": \"admin\", \"password\": \"xxxxxxxxxx\"}, \n", - ")\n", - "response" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "d7b33a9e-17ab-474a-bb38-1da600b88cf7", - "metadata": {}, - "outputs": [], - "source": [ - "access_token_result = response.json()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "799bce38-9933-4610-b450-08ea28adb5ce", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "response = requests.get(\n", - " f\"{ENDPOINT_URL}/api/v2/dags\", \n", - " headers={\n", - " \"Content-Type\": \"application/json\",\n", - " \"Authorization\": f\"Bearer {access_token_result['access_token']}\",\n", - " }, \n", - ")\n", - "response" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "1904e2f6-cc9d-44c5-b8a1-5911f5b2c0c2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'dags': [{'dag_id': 'asset1_producer',\n", - " 'dag_display_name': 'asset1_producer',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.565529Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_decorator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_decorator.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlsSnpCbnFyWW5BfpFVQq1QIAc2AdSg.WpzxtbOARyNWvIbbP0JQazaYepI'},\n", - " {'dag_id': 'asset2_producer',\n", - " 'dag_display_name': 'asset2_producer',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.570916Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_decorator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_decorator.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlsSnpCbnFyWW5BfpFVQq1QIAc2AdSg.WpzxtbOARyNWvIbbP0JQazaYepI'},\n", - " {'dag_id': 'asset_alias_example_alias_consumer',\n", - " 'dag_display_name': 'asset_alias_example_alias_consumer',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.399454Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_alias.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_alias.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [{'name': 'consumer',\n", - " 'dag_id': 'asset_alias_example_alias_consumer'},\n", - " {'name': 'asset-alias', 'dag_id': 'asset_alias_example_alias_consumer'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlsQn5mQmFusVVCrVAgD_EBuR.OFtfcYtzb9c_69whN89vNAdU2AM'},\n", - " {'dag_id': 'asset_alias_example_alias_consumer_with_no_taskflow',\n", - " 'dag_display_name': 'asset_alias_example_alias_consumer_with_no_taskflow',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.708165Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_alias_with_no_taskflow.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_alias_with_no_taskflow.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [{'name': 'consumer',\n", - " 'dag_id': 'asset_alias_example_alias_consumer_with_no_taskflow'},\n", - " {'name': 'asset-alias',\n", - " 'dag_id': 'asset_alias_example_alias_consumer_with_no_taskflow'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJxNyksOQEAMANC7dC0O4DJNmQ6Nzidahoi7s7R8ybth3HNQxkyJYQA-KdWPgWaDDjZWcjkYoyhrmX6DzNiRVMiwiS-YCzrZGrW0vl7wvBoPIrI.44lpVux2LhW9KtFzXyS44K9tr14'},\n", - " {'dag_id': 'asset_alias_example_alias_producer',\n", - " 'dag_display_name': 'asset_alias_example_alias_producer',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.405215Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_alias.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_alias.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'producer',\n", - " 'dag_id': 'asset_alias_example_alias_producer'},\n", - " {'name': 'asset-alias', 'dag_id': 'asset_alias_example_alias_producer'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlsQn5mQmFusVVCrVAgD_EBuR.OFtfcYtzb9c_69whN89vNAdU2AM'},\n", - " {'dag_id': 'asset_alias_example_alias_producer_with_no_taskflow',\n", - " 'dag_display_name': 'asset_alias_example_alias_producer_with_no_taskflow',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.711306Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_alias_with_no_taskflow.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_alias_with_no_taskflow.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'producer',\n", - " 'dag_id': 'asset_alias_example_alias_producer_with_no_taskflow'},\n", - " {'name': 'asset-alias',\n", - " 'dag_id': 'asset_alias_example_alias_producer_with_no_taskflow'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJxNyksOQEAMANC7dC0O4DJNmQ6Nzidahoi7s7R8ybth3HNQxkyJYQA-KdWPgWaDDjZWcjkYoyhrmX6DzNiRVMiwiS-YCzrZGrW0vl7wvBoPIrI.44lpVux2LhW9KtFzXyS44K9tr14'},\n", - " {'dag_id': 'asset_consumes_1',\n", - " 'dag_display_name': 'asset_consumes_1',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.698021Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_assets.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_assets.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [{'name': 'consumes', 'dag_id': 'asset_consumes_1'},\n", - " {'name': 'asset-scheduled', 'dag_id': 'asset_consumes_1'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlhTrFVQq1QIAeDwZmw.-9O6IF8t1Zs8eoutphrDTiiwjZs'},\n", - " {'dag_id': 'asset_consumes_1_and_2',\n", - " 'dag_display_name': 'asset_consumes_1_and_2',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.704079Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_assets.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_assets.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [{'name': 'consumes', 'dag_id': 'asset_consumes_1_and_2'},\n", - " {'name': 'asset-scheduled', 'dag_id': 'asset_consumes_1_and_2'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlhTrFVQq1QIAeDwZmw.-9O6IF8t1Zs8eoutphrDTiiwjZs'},\n", - " {'dag_id': 'asset_consumes_1_never_scheduled',\n", - " 'dag_display_name': 'asset_consumes_1_never_scheduled',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.707469Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_assets.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_assets.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [{'name': 'consumes', 'dag_id': 'asset_consumes_1_never_scheduled'},\n", - " {'name': 'asset-scheduled', 'dag_id': 'asset_consumes_1_never_scheduled'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlhTrFVQq1QIAeDwZmw.-9O6IF8t1Zs8eoutphrDTiiwjZs'},\n", - " {'dag_id': 'asset_consumes_unknown_never_scheduled',\n", - " 'dag_display_name': 'asset_consumes_unknown_never_scheduled',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.710532Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_assets.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_assets.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [{'name': 'asset-scheduled',\n", - " 'dag_id': 'asset_consumes_unknown_never_scheduled'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlhTrFVQq1QIAeDwZmw.-9O6IF8t1Zs8eoutphrDTiiwjZs'},\n", - " {'dag_id': 'asset_produces_1',\n", - " 'dag_display_name': 'asset_produces_1',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.713599Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_assets.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_assets.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'produces', 'dag_id': 'asset_produces_1'},\n", - " {'name': 'asset-scheduled', 'dag_id': 'asset_produces_1'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlhTrFVQq1QIAeDwZmw.-9O6IF8t1Zs8eoutphrDTiiwjZs'},\n", - " {'dag_id': 'asset_produces_2',\n", - " 'dag_display_name': 'asset_produces_2',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.722743Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_assets.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_assets.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'produces', 'dag_id': 'asset_produces_2'},\n", - " {'name': 'asset-scheduled', 'dag_id': 'asset_produces_2'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlhTrFVQq1QIAeDwZmw.-9O6IF8t1Zs8eoutphrDTiiwjZs'},\n", - " {'dag_id': 'asset_s3_bucket_consumer',\n", - " 'dag_display_name': 'asset_s3_bucket_consumer',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.408908Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_alias.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_alias.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [{'name': 'consumer', 'dag_id': 'asset_s3_bucket_consumer'},\n", - " {'name': 'asset', 'dag_id': 'asset_s3_bucket_consumer'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlsQn5mQmFusVVCrVAgD_EBuR.OFtfcYtzb9c_69whN89vNAdU2AM'},\n", - " {'dag_id': 'asset_s3_bucket_consumer_with_no_taskflow',\n", - " 'dag_display_name': 'asset_s3_bucket_consumer_with_no_taskflow',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.714158Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_alias_with_no_taskflow.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_alias_with_no_taskflow.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [{'name': 'consumer',\n", - " 'dag_id': 'asset_s3_bucket_consumer_with_no_taskflow'},\n", - " {'name': 'asset', 'dag_id': 'asset_s3_bucket_consumer_with_no_taskflow'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJxNyksOQEAMANC7dC0O4DJNmQ6Nzidahoi7s7R8ybth3HNQxkyJYQA-KdWPgWaDDjZWcjkYoyhrmX6DzNiRVMiwiS-YCzrZGrW0vl7wvBoPIrI.44lpVux2LhW9KtFzXyS44K9tr14'},\n", - " {'dag_id': 'asset_s3_bucket_producer',\n", - " 'dag_display_name': 'asset_s3_bucket_producer',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.413715Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_alias.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_alias.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'producer', 'dag_id': 'asset_s3_bucket_producer'},\n", - " {'name': 'asset', 'dag_id': 'asset_s3_bucket_producer'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlsQn5mQmFusVVCrVAgD_EBuR.OFtfcYtzb9c_69whN89vNAdU2AM'},\n", - " {'dag_id': 'asset_s3_bucket_producer_with_no_taskflow',\n", - " 'dag_display_name': 'asset_s3_bucket_producer_with_no_taskflow',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.717396Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_alias_with_no_taskflow.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_alias_with_no_taskflow.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'producer',\n", - " 'dag_id': 'asset_s3_bucket_producer_with_no_taskflow'},\n", - " {'name': 'asset', 'dag_id': 'asset_s3_bucket_producer_with_no_taskflow'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJxNyksOQEAMANC7dC0O4DJNmQ6Nzidahoi7s7R8ybth3HNQxkyJYQA-KdWPgWaDDjZWcjkYoyhrmX6DzNiRVMiwiS-YCzrZGrW0vl7wvBoPIrI.44lpVux2LhW9KtFzXyS44K9tr14'},\n", - " {'dag_id': 'asset_with_extra_by_context',\n", - " 'dag_display_name': 'asset_with_extra_by_context',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.141261Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_outlet_event_extra.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_outlet_event_extra.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'produces', 'dag_id': 'asset_with_extra_by_context'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVTkl5bkpJbEp5al5gHJipKiRL2CSqVaANFjHqk.JXKTSwh6GvNZMYAkWx-4Yoz4qjE'},\n", - " {'dag_id': 'asset_with_extra_by_yield',\n", - " 'dag_display_name': 'asset_with_extra_by_yield',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.155165Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_outlet_event_extra.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_outlet_event_extra.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'produces', 'dag_id': 'asset_with_extra_by_yield'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVTkl5bkpJbEp5al5gHJipKiRL2CSqVaANFjHqk.JXKTSwh6GvNZMYAkWx-4Yoz4qjE'},\n", - " {'dag_id': 'asset_with_extra_from_classic_operator',\n", - " 'dag_display_name': 'asset_with_extra_from_classic_operator',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.162525Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_outlet_event_extra.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_outlet_event_extra.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'produces',\n", - " 'dag_id': 'asset_with_extra_from_classic_operator'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVTkl5bkpJbEp5al5gHJipKiRL2CSqVaANFjHqk.JXKTSwh6GvNZMYAkWx-4Yoz4qjE'},\n", - " {'dag_id': 'child_dag',\n", - " 'dag_display_name': 'child_dag',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:28.824967Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_external_task_child_deferrable.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_external_task_child_deferrable.py',\n", - " 'description': None,\n", - " 'timetable_summary': '@once',\n", - " 'timetable_description': 'Once, as soon as possible',\n", - " 'tags': [{'name': 'async', 'dag_id': 'child_dag'},\n", - " {'name': 'core', 'dag_id': 'child_dag'},\n", - " {'name': 'example', 'dag_id': 'child_dag'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2022-01-01T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2022-01-01T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2022-01-01T00:00:00Z',\n", - " 'next_dagrun_run_after': '2022-01-01T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1ykEOgzAMBMC_-FzRO5-xFrwpUU2InLSiqvg7XDiONH-ZPsWcWrBSRuGOtV40vJo8JOjo-UtN2enbfI3WUQxhz7ty74wC14721nnJbmpMjMDkHOpPjhOrJibL.WTHH46K5zlxCpkPYAgnJGSa_PFE'},\n", - " {'dag_id': 'conditional_asset_and_time_based_timetable',\n", - " 'dag_display_name': 'conditional_asset_and_time_based_timetable',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.725604Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_assets.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_assets.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset or 0 1 * * 3',\n", - " 'timetable_description': 'Triggered by assets or At 01:00, only on Wednesday',\n", - " 'tags': [{'name': 'asset-time-based-timetable',\n", - " 'dag_id': 'conditional_asset_and_time_based_timetable'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-02T01:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-02T01:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-02T01:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-02T01:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlhTrFVQq1QIAeDwZmw.-9O6IF8t1Zs8eoutphrDTiiwjZs'},\n", - " {'dag_id': 'consume_1_and_2_with_asset_expressions',\n", - " 'dag_display_name': 'consume_1_and_2_with_asset_expressions',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.734911Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_assets.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_assets.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlhTrFVQq1QIAeDwZmw.-9O6IF8t1Zs8eoutphrDTiiwjZs'},\n", - " {'dag_id': 'consume_1_or_2_with_asset_expressions',\n", - " 'dag_display_name': 'consume_1_or_2_with_asset_expressions',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.738291Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_assets.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_assets.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlhTrFVQq1QIAeDwZmw.-9O6IF8t1Zs8eoutphrDTiiwjZs'},\n", - " {'dag_id': 'consume_1_or_both_2_and_3_with_asset_expressions',\n", - " 'dag_display_name': 'consume_1_or_both_2_and_3_with_asset_expressions',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.741948Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_assets.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_assets.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlhTrFVQq1QIAeDwZmw.-9O6IF8t1Zs8eoutphrDTiiwjZs'},\n", - " {'dag_id': 'consumes_asset_decorator',\n", - " 'dag_display_name': 'consumes_asset_decorator',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.574453Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_decorator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_decorator.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [{'name': 'consumes', 'dag_id': 'consumes_asset_decorator'},\n", - " {'name': 'asset-scheduled', 'dag_id': 'consumes_asset_decorator'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFhenlsSnpCbnFyWW5BfpFVQq1QIAc2AdSg.WpzxtbOARyNWvIbbP0JQazaYepI'},\n", - " {'dag_id': 'example_asset_with_watchers',\n", - " 'dag_display_name': 'example_asset_with_watchers',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.258851Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_asset_with_watchers.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_asset_with_watchers.py',\n", - " 'description': None,\n", - " 'timetable_summary': 'Asset',\n", - " 'timetable_description': 'Triggered by assets',\n", - " 'tags': [],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJxNysENgCAMBdBdejYO4DJNha-QABJaRWPcXY8eX_JumvfiE7hIBk2EU3L96GVVGqghicUDvMSEtLnfEFUY92iBu5gLaDrWi54X72IfAw.a4J5WSVWcmvBquZ0xpow0xGCD7c'},\n", - " {'dag_id': 'example_bash_decorator',\n", - " 'dag_display_name': 'example_bash_decorator',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:29.572178Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_bash_decorator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_bash_decorator.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1yksKgDAMBcC7ZC269zLltYlaSD-kVRTx7rpxOTA3-T2zistIQjPJiVQ_MtZGA5koejzELVFFS_hG68gM4-mvHm1zLKEYerGxXvS8Z5ogSA.GblUchQcsBVZugGxkqyzvsGJVl4'},\n", - " {'dag_id': 'example_bash_operator',\n", - " 'dag_display_name': 'example_bash_operator',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:29.066931Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_bash_operator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_bash_operator.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_bash_operator'},\n", - " {'name': 'example2', 'dag_id': 'example_bash_operator'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1yksKgDAMBcC7ZC269zLl1UQtpB_SKop4d7txOTAP-SOxikuIQjPJhVg6GVulgUwULZzi1qCieemjNiSG8fRXj7q7XMTQso3lpvcDSAMf8Q.v5zlHxgwP327JC1K7Hgb747w8Es'},\n", - " {'dag_id': 'example_branch_datetime_operator',\n", - " 'dag_display_name': 'example_branch_datetime_operator',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:28.034430Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_branch_datetime_operator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_branch_datetime_operator.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_branch_datetime_operator'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1y0EKgCAQRuG7zDpq32Vk1L8SdJRpiiK6e25aPvjeQ_6QmOGEC2gmXFxaz8jrTgMpMls64ZaUkWvoYjeWyBqnn3plCVs_DJYKXG1Qtqpju-n9AMRgJG0.kU7LyGk1nucNL-Ml3EVUlxBo8Q4'},\n", - " {'dag_id': 'example_branch_datetime_operator_2',\n", - " 'dag_display_name': 'example_branch_datetime_operator_2',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:28.049260Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_branch_datetime_operator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_branch_datetime_operator.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'example',\n", - " 'dag_id': 'example_branch_datetime_operator_2'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1y0EKgCAQRuG7zDpq32Vk1L8SdJRpiiK6e25aPvjeQ_6QmOGEC2gmXFxaz8jrTgMpMls64ZaUkWvoYjeWyBqnn3plCVs_DJYKXG1Qtqpju-n9AMRgJG0.kU7LyGk1nucNL-Ml3EVUlxBo8Q4'},\n", - " {'dag_id': 'example_branch_datetime_operator_3',\n", - " 'dag_display_name': 'example_branch_datetime_operator_3',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:28.057728Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_branch_datetime_operator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_branch_datetime_operator.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'example',\n", - " 'dag_id': 'example_branch_datetime_operator_3'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1y0EKgCAQRuG7zDpq32Vk1L8SdJRpiiK6e25aPvjeQ_6QmOGEC2gmXFxaz8jrTgMpMls64ZaUkWvoYjeWyBqnn3plCVs_DJYKXG1Qtqpju-n9AMRgJG0.kU7LyGk1nucNL-Ml3EVUlxBo8Q4'},\n", - " {'dag_id': 'example_branch_dop_operator_v3',\n", - " 'dag_display_name': 'example_branch_dop_operator_v3',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.022252Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_branch_python_dop_operator_3.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_branch_python_dop_operator_3.py',\n", - " 'description': None,\n", - " 'timetable_summary': '*/1 * * * *',\n", - " 'timetable_description': 'Every minute',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_branch_dop_operator_v3'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T09:50:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T09:50:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T09:50:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T09:50:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJxNyjEKgDAMAMC_ZBYXNz8T0jZaoU1CrGIR_66j48HdEA5JhVGoMszAF1X7mGjdYQDnQm07GZetcNH4G8FJYkbrLatgUkM1dmrqOI3W4XkBGOoidg.l4vnIhZXIfSl0iQkl2H6n5EPmkE'},\n", - " {'dag_id': 'example_branch_labels',\n", - " 'dag_display_name': 'example_branch_labels',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:36.878121Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_branch_labels.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_branch_labels.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQkFSXmJWfE5yQmpeYU6xVUKtUCADabHEg.6KVOIC3gQzgoVmfhMnVGijFhpm0'},\n", - " {'dag_id': 'example_branch_operator',\n", - " 'dag_display_name': 'example_branch_operator',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:29.253191Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_branch_operator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_branch_operator.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_branch_operator'},\n", - " {'name': 'example2', 'dag_id': 'example_branch_operator'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1ykEKgCAQBdC7zDpq32Xkq1MJ4yijRRHdvTYtH7yb_K5R2Cky00x8ItePEWujgYwFPR3sliQsJXyjdWiExemv3qBhc6WyoRcb60XPC4mQIME.76RwV3rjfk3EditFnEr3sDW1DoA'},\n", - " {'dag_id': 'example_branch_python_operator_decorator',\n", - " 'dag_display_name': 'example_branch_python_operator_decorator',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:28.435055Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_branch_operator_decorator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_branch_operator_decorator.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'example',\n", - " 'dag_id': 'example_branch_python_operator_decorator'},\n", - " {'name': 'example2',\n", - " 'dag_id': 'example_branch_python_operator_decorator'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1ytEKgCAMQNF_2XPUez8j060SppNpUUT_ngS93QvnBr9nEnYZE8MMfGIqfQnXCgMYC7Z4sFuisGjoojbMhEbTT71hDpvTwoZNzREH_WosFzwv6tIk4w.MYGzi2O3GIeP75A6kp7p1mSIygM'},\n", - " {'dag_id': 'example_complex',\n", - " 'dag_display_name': 'example_complex',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:36.490224Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_complex.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_complex.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_complex'},\n", - " {'name': 'example3', 'dag_id': 'example_complex'},\n", - " {'name': 'example2', 'dag_id': 'example_complex'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQk54OoCr2CSqVaAJJiGgA.Sni-PYBn8P2xXa3RqhLd1-Nza9Y'},\n", - " {'dag_id': 'example_custom_weight',\n", - " 'dag_display_name': 'example_custom_weight',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:36.370206Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_custom_weight.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_custom_weight.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_custom_weight'},\n", - " {'name': 'example2', 'dag_id': 'example_custom_weight'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVQklxaX5OfGl6dmpmeU6BVUKtUCADodHIo.ZIQjVd4rBHDUgZL0-Ib6aiV0xYk'},\n", - " {'dag_id': 'example_dag_decorator',\n", - " 'dag_display_name': 'example_dag_decorator',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:36.613065Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_dag_decorator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_dag_decorator.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_dag_decorator'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTUVXEp6Qm5xclluQX6RVUKtUCADZ9HFY.QdYg_E7_mamwp6vtNiCmO_agx7A'},\n", - " {'dag_id': 'example_display_name',\n", - " 'dag_display_name': 'Sample DAG with Display Name',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:36.738044Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_display_name.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_display_name.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_display_name'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVVkFhfkJFaCNeoVVCrVAgAbvhv-.JJ2mZD5JkX3UTO8ighsW16aIN9A'},\n", - " {'dag_id': 'example_dynamic_task_mapping',\n", - " 'dag_display_name': 'example_dynamic_task_mapping',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.961984Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_dynamic_task_mapping.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_dynamic_task_mapping.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVVUArVkJseXJBZnx-cmFhRk5qXrFVQq1QIADRUfSg.S4X-Q8qiX0o8_a7nX_aUN1xb624'},\n", - " {'dag_id': 'example_dynamic_task_mapping_with_no_taskflow_operators',\n", - " 'dag_display_name': 'example_dynamic_task_mapping_with_no_taskflow_operators',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:37.148480Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_dynamic_task_mapping_with_no_taskflow_operators.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_dynamic_task_mapping_with_no_taskflow_operators.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJxNi8kNgDAMwHbJGzEAy0ShBIhIm6gtlxC7g3jxtGVf0K9pUMZEkaEDPij6iwNNBRrIrFRlYxxFWS38i_NdJGClsmAkd0kT7lJnTPbJUW1Hc85ULZfWT7gfApkqqQ.JO8Hal1o4IMC3AiF_CzxOq8WjIs'},\n", - " {'dag_id': 'example_external_task_marker_child',\n", - " 'dag_display_name': 'example_external_task_marker_child',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:28.688393Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_external_task_marker_dag.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_external_task_marker_dag.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'example2',\n", - " 'dag_id': 'example_external_task_marker_child'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1y0EOQDAURdG9_LEwt5nm0UfEbzW_JRWxdwwMb3LuJcMevdJFBEovrAjpTY85SyNGRVkOumlR6ja-IhdED_PdT1kLLUJdQV5dgK2072_TKfcDx14kaQ.3eCJQm-_iFy_fhlGA1dEWmji_sg'},\n", - " {'dag_id': 'example_external_task_marker_parent',\n", - " 'dag_display_name': 'example_external_task_marker_parent',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:28.700655Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_external_task_marker_dag.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_external_task_marker_dag.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'example2',\n", - " 'dag_id': 'example_external_task_marker_parent'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1y0EOQDAURdG9_LEwt5nm0UfEbzW_JRWxdwwMb3LuJcMevdJFBEovrAjpTY85SyNGRVkOumlR6ja-IhdED_PdT1kLLUJdQV5dgK2072_TKfcDx14kaQ.3eCJQm-_iFy_fhlGA1dEWmji_sg'},\n", - " {'dag_id': 'example_nested_branch_dag',\n", - " 'dag_display_name': 'example_nested_branch_dag',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:34.674977Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_nested_branch_dag.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_nested_branch_dag.py',\n", - " 'description': None,\n", - " 'timetable_summary': '0 0 * * *',\n", - " 'timetable_description': 'At 00:00',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_nested_branch_dag'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T00:00:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T00:00:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJyrVkoqzUvJSY3PS8xNVbJSSq1IzC0AclMS04uVdJSKUnMSSzLLUuPTMnNSc_KTkVTkpRaXpKbEJxUl5iVngNTrFVQq1QIArgId4w.XvW-AUFXCPeOg9HVjH5O5mnrBjg'},\n", - " {'dag_id': 'example_params_trigger_ui',\n", - " 'dag_display_name': 'Params Trigger UI',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:35.529193Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_params_trigger_ui.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_params_trigger_ui.py',\n", - " 'description': 'Example DAG demonstrating the usage DAG params to model a trigger UI with a user form',\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'params', 'dag_id': 'example_params_trigger_ui'},\n", - " {'name': 'example', 'dag_id': 'example_params_trigger_ui'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJxNyksKgDAMBcC7ZC0ewMuEaJ8lkH5IW1HEu-vS5cDctI4cDJwlgRbCKal-DBIbTeQw6XqAdzVY2X6jiktq3F1jhPPQuV70vLA3Hhw.ohMp6G0XKIXbXPxh8HRrbtVIbO8'},\n", - " {'dag_id': 'example_params_ui_tutorial',\n", - " 'dag_display_name': 'Params UI tutorial',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:34.540884Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_params_ui_tutorial.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_params_ui_tutorial.py',\n", - " 'description': 'DAG demonstrating various options for a trigger form generated by DAG params',\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'params', 'dag_id': 'example_params_ui_tutorial'},\n", - " {'name': 'example', 'dag_id': 'example_params_ui_tutorial'},\n", - " {'name': 'ui', 'dag_id': 'example_params_ui_tutorial'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJxNyksKgDAMBcC7ZC0ewMuEZxslkH5oG1HEu-vS5cDctHqOJpyRhBaSE6l-jNg7TdTEMPQQ3tTESviNiobU2ZWHj9IUNteLnhfQDR6c.HzD1VPC9iiMR7-6Aa4pQds1J1Cw'},\n", - " {'dag_id': 'example_passing_params_via_test_command',\n", - " 'dag_display_name': 'example_passing_params_via_test_command',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:34.372149Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'example_passing_params_via_test_command.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/example_passing_params_via_test_command.py',\n", - " 'description': None,\n", - " 'timetable_summary': '*/1 * * * *',\n", - " 'timetable_description': 'Every minute',\n", - " 'tags': [{'name': 'example',\n", - " 'dag_id': 'example_passing_params_via_test_command'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': '2025-07-08T09:50:00Z',\n", - " 'next_dagrun_data_interval_start': '2025-07-08T09:50:00Z',\n", - " 'next_dagrun_data_interval_end': '2025-07-08T09:50:00Z',\n", - " 'next_dagrun_run_after': '2025-07-08T09:50:00Z',\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJxNysEJgDAMQNFdchYHcJkQ21gKSVqaWhRxd3v09HnwH9hPi8JopAwb8EVaJyMlhwUaC_U8GI8sLCX8jkru2dJsI3UcmbCzdwxFlSyu9Yb3A4XkI9w.VNaKWaDywj5t8vSldz59vWTKMiA'},\n", - " {'dag_id': 'example_python_decorator',\n", - " 'dag_display_name': 'example_python_decorator',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:29.410130Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_python_decorator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_python_decorator.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_python_decorator'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1yjEKgDAMAMC_ZBbd_UyJTdRCm5Q0ikX8uy6OB3fDcghlDoKFYQa-sNSPhFuDAYwzejo5rClz1viN5iiERtNfa_ddJRBHNXS1sXZ4Xq3SIUw.ne5Y3q1zrcjwXhIaEEPewWltENY'},\n", - " {'dag_id': 'example_python_operator',\n", - " 'dag_display_name': 'example_python_operator',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:27.880644Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_python_operator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_python_operator.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_python_operator'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1yjEKgDAMAMC_ZBbd_UyJJmqhTUIbxSL-3S6OB_fAcgolDoKZYQa-MVsn4V5hgMIJPV4ctpg46dpHdRTCQtNfrfmhEtS4oGsZrcH7AY03IPU.08z1nSaxTJa6tvb3PzLHswBpeZ8'},\n", - " {'dag_id': 'example_sensor_decorator',\n", - " 'dag_display_name': 'example_sensor_decorator',\n", - " 'is_paused': True,\n", - " 'is_stale': False,\n", - " 'last_parsed_time': '2025-07-08T09:50:27.376169Z',\n", - " 'last_expired': None,\n", - " 'bundle_name': 'example_dags',\n", - " 'bundle_version': None,\n", - " 'relative_fileloc': 'standard/example_sensor_decorator.py',\n", - " 'fileloc': '/home/norman/projects/airflow/.venv/lib/python3.12/site-packages/airflow/example_dags/standard/example_sensor_decorator.py',\n", - " 'description': None,\n", - " 'timetable_summary': None,\n", - " 'timetable_description': 'Never, external triggers only',\n", - " 'tags': [{'name': 'example', 'dag_id': 'example_sensor_decorator'}],\n", - " 'max_active_tasks': 16,\n", - " 'max_active_runs': 16,\n", - " 'max_consecutive_failed_dag_runs': 0,\n", - " 'has_task_concurrency_limits': False,\n", - " 'has_import_errors': False,\n", - " 'next_dagrun_logical_date': None,\n", - " 'next_dagrun_data_interval_start': None,\n", - " 'next_dagrun_data_interval_end': None,\n", - " 'next_dagrun_run_after': None,\n", - " 'owners': ['airflow'],\n", - " 'file_token': '.eJw1yjEKgDAMAMC_ZBbd_UyJTZRCmpSkiiL-XRfHg7th2ZWEk2JlmIFPrO0j4RYwgLNgLwentQiL5W9ERyV0mv4arGGeiLM5dvOxXfC8rRUhRA.m5x3npqmhvjox4dukQQxPS8tN24'}],\n", - " 'total_entries': 78}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "response.json()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2da28acc-d0d8-4e32-b069-a0ca6d33bb26", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.13.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/s2gos-airflow/pixi.lock b/s2gos-airflow/pixi.lock deleted file mode 100644 index 835662c..0000000 --- a/s2gos-airflow/pixi.lock +++ /dev/null @@ -1,3961 +0,0 @@ -version: 6 -environments: - default: - channels: - - url: https://conda.anaconda.org/conda-forge/ - indexes: - - https://pypi.org/simple - packages: - linux-64: - - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1423503_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.3-hee844dc_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.1-h7b32b05_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.11-h9e4cc4f_0_cpython.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - pypi: https://files.pythonhosted.org/packages/02/d5/349aba3dc421e73cbd4958c0ce0a4f1aa3a738bc0d7de75d2f40ed43a535/a2wsgi-1.10.10-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4d/1f/f797b684fb4e11a5066ab464b460b5cfdbaedea9c4a3d0f0afc8e894ada0/aiologic-0.14.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f5/10/6c25ed6de94c49f88a91fa5018cb4c0f3625f31d5be9f771ebe5cc7cd506/aiosqlite-0.21.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/62/96b5217b742805236614f05904541000f55422a6060a90d7fd4ce26c172d/alembic-1.16.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/c8/e5135ee8e263d9f1eae5c9258b4f35924eb5d8f8b883b03a4923453ae9af/apache_airflow-3.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/fe/6efbbb6f07fd4031d19a2894d51ca6210cc5ae9365e21e4e5d92817bef63/apache_airflow_core-3.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9d/06/5705308c34a368f1146f4920945f620f3b69ba82fa52ea34464e3a9f74ab/apache_airflow_providers_common_compat-1.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/ef/b1e3503c2d8e9b1e9e351315426f5d94a5cd3a2cb344b74f3cbdbf0e2b6f/apache_airflow_providers_common_io-1.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/07/5dc81b135b000620bde3466734e21f7a2c2ad9e8f4f0a559de8879f21334/apache_airflow_providers_common_sql-1.27.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/64/e9/a75c7cb806f054764454686651375c2f99aeabbe90cc2fc7d37666d93dbf/apache_airflow_providers_smtp-2.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/08/0c/5893b77b5b5fae795cc47ba67e33ae28ffae0b4d3b70f028f1e35d99f5ad/apache_airflow_providers_standard-1.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/90/b170b78a686ec5af2525f96df99a946c023483102ecd11a8d1cbbd1a7b66/apache_airflow_task_sdk-1.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/da/e42d7a9d8dd33fa775f467e4028a47936da2f01e4b0e561f9ba0d74cb0ca/argcomplete-3.6.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/f7/378254e6dd7ae6f31fe40c8649eea7d4832a42243acaf0f1fff9083b2bed/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/3c/0464dcada90d5da0e71018c04a140ad6349558afb30b3051b4264cc5b965/asgiref-3.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fc/55/96142937f66150805c25c4d0f31ee4132fd33497753400734f9dfdcbdc66/bleach-6.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f3/67/442922a6758c1059907e3030e1a978a11533d08ac459ccd3cd255596b316/cadwyn-5.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4f/52/34c6cf5bb9285074dc3531c437b3919e825d976fde097a7a73f79e726d03/certifi-2025.7.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e3/51/9b208e85196941db2f0654ad0357ca6388ab3ed67efdbfc799f35d1f83aa/colorlog-6.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/75/49e5bfe642f71f272236b5b2d2691cf915a7283cc0ceda56357b61daa538/comm-0.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/13/13576941bf7cf95026abae43d8427c812c0054408212bf8ed490eda846b0/crc32c-2.7.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/88/20/2cfe598ead23a715a00beb716477cfddd3e5948cf203c372d02221e5b0c6/cron_descriptor-1.4.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/4b/290b4c3efd6417a8b0c284896de19b1d5855e6dbdb97d2a35e68fa42de85/croniter-6.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/ef/3333295ed58d900a13c92806b67e62f27876845a9a908c939f040887cca9/cryptography-45.0.5-cp311-abi3-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/99/8d/7f6ef1097e7fecf26b4ef72338d08e41644a41b7ee958a19f494ffcffc29/debugpy-1.8.15-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/c6/ac0b6c1e2d138f1002bcf799d330bd6d85084fece321e662a14223794041/Deprecated-1.2.18-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/47/d63c60f59a59467fda0f93f46335c9d18526d7071f025cb5b89d5353ea42/fastapi-0.116.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e0/3f/6ad3103c5f59208baf4c798526daea6a74085bb35d1c161c501863470476/fastapi_cli-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/cf/8635cd778b7d89714325b967a28c05865a2b6cab4c0b4b30561df4704f24/fastapi_cloud_cli-0.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/2b/0817a2b257fe88725c25589d89aec060581aabf668707a8d03b2e9e0cb2a/fastjsonschema-2.21.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3d/68/9d4508e893976286d2ead7f8f571314af6c2037af34853a30fd769c02e9d/flask-3.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2f/e0/014d5d9d7a4564cf1c40b5039bc882db69fd881111e03ab3657ac0b218e2/fsspec-2025.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/86/f1/62a193f0227cf15a920390abe675f386dec35f7ae3ffe6da582d3ade42c7/googleapis_common_protos-1.70.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f6/f6/c82ac1851c60851302d8581680573245c8fc300253fc1ff741ae74a6c24d/greenlet-3.2.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/6e/66/e8fe779b23b5a26d1b6949e5c70bc0a5fd08f61a6ec5ac7760d589229511/grpcio-1.73.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/cb/7d/6dac2a6e1eba33ee43f318edbed4ff29151a49b5d37f080aad1e6469bca4/gunicorn-23.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/d8/b644c44acc1368938317d76ac991c9bba1166311880bcc0ac297cb9d6bd7/httptools-0.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1f/3d/00813c3d9b46e3dcd88bd4530e0a3c63c0509e5d8c9eff34723ea243ab04/ipykernel-6.30.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/63/f8/0031ee2b906a15a33d6bfc12dd09c3dfa966b3cb5b284ecfb7549e6ac3c4/ipython-9.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/58/6a/9166369a2f092bd286d24e6307de555d63616e8ddb373ebad2b5635ca4cd/ipywidgets-8.1.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c1/11/114d0a5f4dabbdcedc1125dee0888514c3c3b16d3e9facad87ed96fad97c/isort-6.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/41/9f/3500910d5a98549e3098807493851eeef2b89cdd3032227558a104dfe926/json5-0.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fe/54/c86cd8e011fe98803d7e382fd67c0df5ceab8d2b7ad8c5a81524f791551c/jsonschema-4.25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/64/285f20a31679bf547b75602702f7800e74dbabae36ef324f716c02804753/jupyter-1.1.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/77/71d78d58f15c22db16328a476426f7ac4a60d3a5a7ba3b9627ee2f7903d4/jupyter_console-6.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2f/57/6bffd4b20b88da3800c5d691e0337761576ee688eb01299eae865689d2df/jupyter_core-5.8.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/47/7c/12f68daf85b469b4896d5e4a629baa33c806d61de75ac5b39d8ef27ec4a2/jupyter_lsp-2.2.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/1f/5ebbced977171d09a7b0c08a285ff9a20aafb9c51bde07e52349ff1ddd71/jupyter_server-2.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/47/74/e144ce85b34414e44b14c1f6bf2e3bfe17964c8e5670ebdc7629f2e53672/jupyterlab-4.4.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/6a/ca128561b22b60bd5a0c4ea26649e68c8556b82bc70a0c396eebc977fe86/jupyterlab_widgets-3.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/00/d90b10b962b4277f5e64a78b6609968859ff86889f5b898c1a778c06ec00/lark-1.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/1e/fb441c07b6662ec1fc92b249225ba6e6e5221b05623cb0131d082f782edc/lazy_object_proxy-1.11.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7d/7d/eb341bdc11f1147e7edeccffd0f2f785eff014e72134f5e46067472012b0/libcst-1.8.2-cp312-cp312-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/04/1e/b832de447dee8b582cac175871d2f6c3d5077cc56d5575cadba1fd1cccfa/linkify_it_py-2.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c8/22/9460e311f340cb62d26a38c419b1381b8593b0bb6b5d1f056938b086d362/lockfile-0.12.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/fb/99f81ac72ae23375f22b7afdb7642aba97c00a713c217124420147681a2f/mako-1.3.10-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b6/4b/6497ffb463b1b75e04b348ef31070606d43e3c503fa295383538ded999c9/methodtools-0.4.7-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2b/9f/7ba6f94fc1e9ac3d2b853fdff3035fb2fa5afbed898c4a72b8a020610594/more_itertools-10.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d0/ef/c5422ce8af73928d194a6606f8ae36e93a52fd5e8df5abd366903a5ca8da/msgspec-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/0b/64/d6120eca3835baf7179e6797a0b61d6c47e0bc2324b1f6819d8428d5b9ba/mypy-1.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/c0/e64d2047fd752249b0b69f6aee2a7049eb94e7273e5baabc8b8ad05cc068/notebook-7.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1b/f5/515f98d659ab0cbe3738da153eddae22186fd38f05a808511e10f04cf679/numcodecs-0.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/6e/45/c51cb248e679a6c6ab14b7a8e3ead3f4a3fe7425fc7a6f98b3f147bec532/numpy-2.3.1-cp312-cp312-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1d/5a/3f8d078dbf55d18442f6a2ecedf6786d81d7245844b2b20ce2b8ad6f0307/opentelemetry_api-1.35.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cf/db/2da28358d3101ca936c1643becbb4ebd69e9e48acf27f153d735a4813c6b/opentelemetry_exporter_otlp-1.35.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5a/2c/e31dd3c719bff87fa77391eb7f38b1430d22868c52312cba8aad60f280e5/opentelemetry_exporter_otlp_proto_common-1.35.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/a6/3f60a77279e6a3dc21fc076dcb51be159a633b0bba5cba9fb804062a9332/opentelemetry_exporter_otlp_proto_grpc-1.35.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/71/f118cd90dc26797077931dd598bde5e0cc652519db166593f962f8fcd022/opentelemetry_exporter_otlp_proto_http-1.35.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/00/a7/3f05de580da7e8a8b8dff041d3d07a20bf3bb62d3bcc027f8fd669a73ff4/opentelemetry_proto-1.35.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/4f/8e32b757ef3b660511b638ab52d1ed9259b666bdeeceba51a082ce3aea95/opentelemetry_sdk-1.35.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/3f/e80c1b017066a9d999efffe88d1cce66116dcf5cb7f80c41040a83b6e03b/opentelemetry_semantic_conventions-0.56b0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/01/e383018feba0a1ead6cf5fe8728e5d767fee02f06a3d800e82c489e5daaf/pandas-2.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/5d/f7a1d693e5c0f789185117d5c1d5bee104f5b0d9fbf061d715fb61c840a8/pendulum-3.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/32/ae/ec06af4fe3ee72d16973474f122541746196aaa16cea6f66d18b963c6177/prometheus_client-0.22.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ce/4f/5249960887b1fbe561d9ff265496d170b55a735b76724f10ef19f9e40716/prompt_toolkit-3.0.51-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/b1/b59d405d64d31999244643d88c45c8241c58f17cc887e73bcb90602327f8/protobuf-6.31.1-cp39-abi3-manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/45/3c/b88167e2d6785c0e781ee5d498b07472aeb9b6765da3b19e7cc9e0813841/python_daemon-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/08/20/0f2523b9e50a8052bc6a8b732dfc8568abbdc42010aef03a2d750bdab3b2/python_json_logger-3.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/69/9a/9ea7e230feda9400fb0ae0d61d7d6ddda635e718d941c44eeab22a179d34/pyzmq-27.0.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b8/09/d5ff873d2579da0082c9afbaad8efde9765aa9bc15875c477fe577f59c09/retryhttp-1.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/f6/5fc0574af5379606ffd57a4b68ed88f9b415eb222047fe023aefcc00a648/rich_argparse-1.7.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/78/39/c0fd75955aa963a15c642dfe6fb2acdd1fd2114028ec5ff2e2fd26218ad7/rich_toolkit-0.14.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/80/c8/b91afda10bd5ca1e3a80463340b899c0dc26a7750a9f3c94f668585c7f40/rignore-0.6.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2e/77/87d7bfabfc4e821caa35481a2ff6ae0b73e6a391bb6b343db2c91c2b9844/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/64/f4/e3cd7f7bda646526f09693e2e02bd83d85fff8a8222c52cf9681c0d30843/ruff-0.12.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/dc/4d825d5eb6e924dfcc6a91c8185578a7b0a5c41fd2416a6f49c8226d6ef9/sentry_sdk-2.33.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e3/fb/5e9b5068df9e9f31a722a775a5e8322a29a638eaaa3eac5ea7f0b35e6314/setproctitle-1.3.6-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/8b/f45dd378f6c97e8ff9332ff3d03ecb0b8c491be5bb7a698783b5a2f358ec/SQLAlchemy-1.4.54-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fd/67/d75d119e70863e0519c8eec5fc66714d34ad1ee9e5e73bf4fc8e3d259fac/SQLAlchemy_JSONField-1.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d5/f0/dc4757b83ac1ab853cf222df8535ed73973e0c203d983982ba7b8bc60508/SQLAlchemy_Utils-0.41.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/1f/b876b1f83aef204198a42dc101613fefccb32258e5428b5f9259677864b4/starlette-0.47.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/4a/97ee6973e3a73c74c8120d59829c3861ea52210667ec3e7a16045c62b64d/structlog-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a2/1c/a6b5d90a9ca479805798276728ccbbdff0c7228e2ea93b1f731779d635e3/svcs-25.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4f/bd/de8d508070629b6d84a30d01d57e4a65c69aa7f5abe7560b8fad3b50ea59/termcolor-3.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7d/f7/0c48ba992d875521ac761e6e04b0a1750f8150ae42ea26df1852d6a98942/tornado-6.5.1-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/42/3efaf858001d2c2913de7f354563e3a3a2f0decae3efe98427125a8f441e/typer-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/72/52/43e70a8e57fefb172c22a21000b03ebcc15e47e97f5cb8495b9c2832efb4/types_python_dateutil-2.9.0.20250708-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3d/ea/0be9258c5a4fa1ba2300111aa5a0767ee6d18eb3fd20e91616c12082284d/types_requests-2.32.4.20250611-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/37/87/1f677586e8ac487e29672e4b17455758fce261de06a0d086167bb760361a/uc_micro_py-1.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/4d/2e577f6db7aa0f932d19f799c18f604b2b302c65f733419b900ec07dbade/universal_pathlib-0.2.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3d/b2/93faaab7962e2aa8d6e174afb6f76be2ca0ce89fde14d3af835acebcaa59/uuid6-2025.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d2/e2/dc81b1bd1dcfe91735810265e9d26bc8ec5da45b4c0f6237e286819194c3/uvicorn-0.35.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/06/a7/b4e6a19925c900be9f98bec0a75e6e8f79bb53bdeb891916609ab3958967/uvloop-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/8c/77/e3362fe308358dc9f8588102481e599c83e1b91c2ae843780a7ded939a35/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/51/5447876806d1088a0f8f71e16542bf350918128d0a69437df26047c8e46f/widgetsnbextension-4.0.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/2d/3557ee32d8268b04ce8aada3212b0d49f2ddcf86dc200f3999a772262dc5/wirerope-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/5a/04cde32b07a7431d4ed0553a76fdb7a61270e78c5fd5a603e190ac389f14/wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b2/ea/9554e5fb78eda4dbc9e9ccaf23034166fe3e9ea9af82ea6204b9578434bc/xarray-2025.7.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - - pypi: ../s2gos-common - - pypi: ../s2gos-server -packages: -- conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 - md5: d7c89558ba9fa0495403155b64376d81 - license: None - purls: [] - size: 2562 - timestamp: 1578324546067 -- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - build_number: 16 - sha256: fbe2c5e56a653bebb982eda4876a9178aedfc2b545f25d0ce9c4c0b508253d22 - md5: 73aaf86a425cc6e73fcf236a5a46396d - depends: - - _libgcc_mutex 0.1 conda_forge - - libgomp >=7.5.0 - constrains: - - openmp_impl 9999 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 23621 - timestamp: 1650670423406 -- pypi: https://files.pythonhosted.org/packages/02/d5/349aba3dc421e73cbd4958c0ce0a4f1aa3a738bc0d7de75d2f40ed43a535/a2wsgi-1.10.10-py3-none-any.whl - name: a2wsgi - version: 1.10.10 - sha256: d2b21379479718539dc15fce53b876251a0efe7615352dfe49f6ad1bc507848d - requires_dist: - - typing-extensions ; python_full_version < '3.11' - requires_python: '>=3.8.0' -- pypi: https://files.pythonhosted.org/packages/4d/1f/f797b684fb4e11a5066ab464b460b5cfdbaedea9c4a3d0f0afc8e894ada0/aiologic-0.14.0-py3-none-any.whl - name: aiologic - version: 0.14.0 - sha256: cc59d39dc1d5e2575b4a6b5faf678b551fb0f910c7cb42e4c5f5689ffedcce78 - requires_dist: - - wrapt>=1.16.0 - - anyio>=3.0.0 ; extra == 'anyio' - - curio>=1.4 ; extra == 'curio' - - docutils>=0.17 ; extra == 'docs' - - myst-parser ; extra == 'docs' - - packaging ; extra == 'docs' - - sphinx ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx-inline-tabs ; extra == 'docs' - - sphinx-rtd-theme ; extra == 'docs' - - eventlet>=0.17.0 ; extra == 'eventlet' - - gevent>=21.1.0 ; extra == 'gevent' - - sniffio>=1.3.0 ; extra == 'sniffio' - - trio>=0.23.0 ; extra == 'trio' - - trio-asyncio>=0.13.0 ; extra == 'trio-asyncio' - - typing-extensions>=4.1.0 ; extra == 'typing-extensions' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/f5/10/6c25ed6de94c49f88a91fa5018cb4c0f3625f31d5be9f771ebe5cc7cd506/aiosqlite-0.21.0-py3-none-any.whl - name: aiosqlite - version: 0.21.0 - sha256: 2549cf4057f95f53dcba16f2b64e8e2791d7e1adedb13197dd8ed77bb226d7d0 - requires_dist: - - typing-extensions>=4.0 - - attribution==1.7.1 ; extra == 'dev' - - black==24.3.0 ; extra == 'dev' - - build>=1.2 ; extra == 'dev' - - coverage[toml]==7.6.10 ; extra == 'dev' - - flake8==7.0.0 ; extra == 'dev' - - flake8-bugbear==24.12.12 ; extra == 'dev' - - flit==3.10.1 ; extra == 'dev' - - mypy==1.14.1 ; extra == 'dev' - - ufmt==2.5.1 ; extra == 'dev' - - usort==1.0.8.post1 ; extra == 'dev' - - sphinx==8.1.3 ; extra == 'docs' - - sphinx-mdinclude==0.6.1 ; extra == 'docs' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c2/62/96b5217b742805236614f05904541000f55422a6060a90d7fd4ce26c172d/alembic-1.16.4-py3-none-any.whl - name: alembic - version: 1.16.4 - sha256: b05e51e8e82efc1abd14ba2af6392897e145930c3e0a2faf2b0da2f7f7fd660d - requires_dist: - - sqlalchemy>=1.4.0 - - mako - - typing-extensions>=4.12 - - tomli ; python_full_version < '3.11' - - tzdata ; extra == 'tz' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - name: annotated-types - version: 0.7.0 - sha256: 1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 - requires_dist: - - typing-extensions>=4.0.0 ; python_full_version < '3.9' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl - name: anyio - version: 4.9.0 - sha256: 9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c - requires_dist: - - exceptiongroup>=1.0.2 ; python_full_version < '3.11' - - idna>=2.8 - - sniffio>=1.1 - - typing-extensions>=4.5 ; python_full_version < '3.13' - - trio>=0.26.1 ; extra == 'trio' - - anyio[trio] ; extra == 'test' - - blockbuster>=1.5.23 ; extra == 'test' - - coverage[toml]>=7 ; extra == 'test' - - exceptiongroup>=1.2.0 ; extra == 'test' - - hypothesis>=4.0 ; extra == 'test' - - psutil>=5.9 ; extra == 'test' - - pytest>=7.0 ; extra == 'test' - - trustme ; extra == 'test' - - truststore>=0.9.1 ; python_full_version >= '3.10' and extra == 'test' - - uvloop>=0.21 ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and sys_platform != 'win32' and extra == 'test' - - packaging ; extra == 'doc' - - sphinx~=8.2 ; extra == 'doc' - - sphinx-rtd-theme ; extra == 'doc' - - sphinx-autodoc-typehints>=1.2.0 ; extra == 'doc' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/e7/c8/e5135ee8e263d9f1eae5c9258b4f35924eb5d8f8b883b03a4923453ae9af/apache_airflow-3.0.2-py3-none-any.whl - name: apache-airflow - version: 3.0.2 - sha256: e598464d5fc14c589999922151bdc6b4f7541aa716e623b2c56d3cbc74e1753d - requires_dist: - - apache-airflow-core==3.0.2 - - apache-airflow-task-sdk>=1.0.0,<1.1.0 - - apache-airflow-providers-amazon[aiobotocore]>=9.6.0 ; extra == 'aiobotocore' - - apache-airflow-providers-airbyte>=5.0.0 ; extra == 'airbyte' - - apache-airflow-providers-alibaba>=3.0.0 ; extra == 'alibaba' - - amqp>=5.2.0 ; extra == 'all' - - apache-airflow-core[all] ; extra == 'all' - - apache-airflow-core[async] ; extra == 'all' - - apache-airflow-core[graphviz] ; extra == 'all' - - apache-airflow-core[kerberos] ; extra == 'all' - - apache-airflow-core[otel] ; extra == 'all' - - apache-airflow-core[sentry] ; extra == 'all' - - apache-airflow-core[statsd] ; extra == 'all' - - apache-airflow-providers-airbyte>=5.0.0 ; extra == 'all' - - apache-airflow-providers-alibaba>=3.0.0 ; extra == 'all' - - apache-airflow-providers-amazon>=9.0.0 ; extra == 'all' - - apache-airflow-providers-amazon[aiobotocore]>=9.6.0 ; extra == 'all' - - apache-airflow-providers-amazon[s3fs] ; extra == 'all' - - apache-airflow-providers-apache-beam>=5.8.1 ; extra == 'all' - - apache-airflow-providers-apache-cassandra>=3.7.0 ; extra == 'all' - - apache-airflow-providers-apache-drill>=2.8.1 ; extra == 'all' - - apache-airflow-providers-apache-druid>=3.12.0 ; extra == 'all' - - apache-airflow-providers-apache-flink>=1.6.0 ; extra == 'all' - - apache-airflow-providers-apache-hdfs ; extra == 'all' - - apache-airflow-providers-apache-hdfs>=4.6.0 ; extra == 'all' - - apache-airflow-providers-apache-hive>=8.2.1 ; extra == 'all' - - apache-airflow-providers-apache-iceberg>=1.2.0 ; extra == 'all' - - apache-airflow-providers-apache-impala>=1.5.2 ; extra == 'all' - - apache-airflow-providers-apache-kafka>=1.6.1 ; extra == 'all' - - apache-airflow-providers-apache-kylin>=3.8.0 ; extra == 'all' - - apache-airflow-providers-apache-livy>=3.9.2 ; extra == 'all' - - apache-airflow-providers-apache-pig>=4.6.0 ; extra == 'all' - - apache-airflow-providers-apache-pinot>=4.5.1 ; extra == 'all' - - apache-airflow-providers-apache-spark>=4.11.1 ; extra == 'all' - - apache-airflow-providers-apprise>=1.4.1 ; extra == 'all' - - apache-airflow-providers-arangodb>=2.7.0 ; extra == 'all' - - apache-airflow-providers-asana>=2.7.0 ; extra == 'all' - - apache-airflow-providers-atlassian-jira>=2.7.1 ; extra == 'all' - - apache-airflow-providers-celery>=3.8.3 ; extra == 'all' - - apache-airflow-providers-cloudant>=4.0.1 ; extra == 'all' - - apache-airflow-providers-cncf-kubernetes>=9.0.0 ; extra == 'all' - - apache-airflow-providers-cohere>=1.4.0 ; extra == 'all' - - apache-airflow-providers-common-compat>=1.2.1 ; extra == 'all' - - apache-airflow-providers-common-io>=1.4.2 ; extra == 'all' - - apache-airflow-providers-common-messaging>=1.0.1 ; extra == 'all' - - apache-airflow-providers-common-sql>=1.18.0 ; extra == 'all' - - apache-airflow-providers-common-sql[pandas] ; extra == 'all' - - apache-airflow-providers-common-sql[polars] ; extra == 'all' - - apache-airflow-providers-databricks>=6.11.0 ; extra == 'all' - - apache-airflow-providers-datadog>=3.8.0 ; extra == 'all' - - apache-airflow-providers-dbt-cloud>=3.11.0 ; extra == 'all' - - apache-airflow-providers-dingding>=3.7.0 ; extra == 'all' - - apache-airflow-providers-discord>=3.9.0 ; extra == 'all' - - apache-airflow-providers-docker>=3.14.1 ; extra == 'all' - - apache-airflow-providers-edge3>=1.0.0 ; extra == 'all' - - apache-airflow-providers-elasticsearch>=5.5.2 ; extra == 'all' - - apache-airflow-providers-exasol>=4.6.1 ; extra == 'all' - - apache-airflow-providers-fab ; extra == 'all' - - apache-airflow-providers-fab>=2.2.0 ; extra == 'all' - - apache-airflow-providers-facebook>=3.7.0 ; extra == 'all' - - apache-airflow-providers-ftp>=3.12.0 ; extra == 'all' - - apache-airflow-providers-git>=0.0.2 ; extra == 'all' - - apache-airflow-providers-github>=2.8.0 ; extra == 'all' - - apache-airflow-providers-google>=10.24.0 ; extra == 'all' - - apache-airflow-providers-grpc>=3.7.0 ; extra == 'all' - - apache-airflow-providers-hashicorp>=4.0.0 ; extra == 'all' - - apache-airflow-providers-http>=4.13.2 ; extra == 'all' - - apache-airflow-providers-imap>=3.8.0 ; extra == 'all' - - apache-airflow-providers-influxdb>=2.8.0 ; extra == 'all' - - apache-airflow-providers-jdbc>=4.5.2 ; extra == 'all' - - apache-airflow-providers-jenkins>=3.7.2 ; extra == 'all' - - apache-airflow-providers-microsoft-azure>=10.5.1 ; extra == 'all' - - apache-airflow-providers-microsoft-mssql>=3.9.2 ; extra == 'all' - - apache-airflow-providers-microsoft-psrp>=3.0.0 ; extra == 'all' - - apache-airflow-providers-microsoft-winrm>=3.6.1 ; extra == 'all' - - apache-airflow-providers-mongo>=4.2.2 ; extra == 'all' - - apache-airflow-providers-mysql>=5.7.2 ; extra == 'all' - - apache-airflow-providers-neo4j>=3.8.0 ; extra == 'all' - - apache-airflow-providers-odbc>=4.8.0 ; extra == 'all' - - apache-airflow-providers-openai>=1.5.0 ; extra == 'all' - - apache-airflow-providers-openfaas>=3.7.0 ; extra == 'all' - - apache-airflow-providers-openlineage>=2.1.3 ; extra == 'all' - - apache-airflow-providers-opensearch>=1.5.0 ; extra == 'all' - - apache-airflow-providers-opsgenie>=5.8.0 ; extra == 'all' - - apache-airflow-providers-oracle>=3.12.0 ; extra == 'all' - - apache-airflow-providers-pagerduty>=3.8.1 ; extra == 'all' - - apache-airflow-providers-papermill>=3.8.2 ; extra == 'all' - - apache-airflow-providers-pgvector>=1.4.0 ; extra == 'all' - - apache-airflow-providers-pinecone>=2.1.1 ; extra == 'all' - - apache-airflow-providers-postgres>=5.13.1 ; extra == 'all' - - apache-airflow-providers-presto>=5.7.0 ; extra == 'all' - - apache-airflow-providers-qdrant>=1.3.0 ; extra == 'all' - - apache-airflow-providers-redis>=4.0.0 ; extra == 'all' - - apache-airflow-providers-salesforce>=5.9.0 ; extra == 'all' - - apache-airflow-providers-samba>=4.9.0 ; extra == 'all' - - apache-airflow-providers-segment>=3.7.0 ; extra == 'all' - - apache-airflow-providers-sendgrid>=4.0.0 ; extra == 'all' - - apache-airflow-providers-sftp>=5.0.0 ; extra == 'all' - - apache-airflow-providers-singularity>=3.7.0 ; extra == 'all' - - apache-airflow-providers-slack>=8.9.1 ; extra == 'all' - - apache-airflow-providers-smtp>=1.8.1 ; extra == 'all' - - apache-airflow-providers-snowflake>=5.8.0 ; extra == 'all' - - apache-airflow-providers-sqlite>=3.9.1 ; extra == 'all' - - apache-airflow-providers-ssh>=3.14.0 ; extra == 'all' - - apache-airflow-providers-standard>=0.0.1 ; extra == 'all' - - apache-airflow-providers-tableau>=5.0.0 ; extra == 'all' - - apache-airflow-providers-telegram>=4.7.0 ; extra == 'all' - - apache-airflow-providers-teradata>=2.6.1 ; extra == 'all' - - apache-airflow-providers-trino>=5.8.1 ; extra == 'all' - - apache-airflow-providers-vertica>=3.9.1 ; extra == 'all' - - apache-airflow-providers-weaviate>=3.0.0 ; extra == 'all' - - apache-airflow-providers-yandex>=4.0.0 ; extra == 'all' - - apache-airflow-providers-ydb>=1.4.0 ; extra == 'all' - - apache-airflow-providers-zendesk>=4.9.0 ; extra == 'all' - - atlasclient>=0.1.2 ; extra == 'all' - - authlib>=1.0.0 ; extra == 'all' - - cloudpickle>=2.2.1 ; extra == 'all' - - python-ldap>=3.4.4 ; extra == 'all' - - uv>=0.7.8 ; extra == 'all' - - apache-airflow-core[all] ; extra == 'all-core' - - apache-airflow-providers-amazon>=9.0.0 ; extra == 'amazon' - - atlasclient>=0.1.2 ; extra == 'apache-atlas' - - apache-airflow-providers-apache-beam>=5.8.1 ; extra == 'apache-beam' - - apache-airflow-providers-apache-cassandra>=3.7.0 ; extra == 'apache-cassandra' - - apache-airflow-providers-apache-drill>=2.8.1 ; extra == 'apache-drill' - - apache-airflow-providers-apache-druid>=3.12.0 ; extra == 'apache-druid' - - apache-airflow-providers-apache-flink>=1.6.0 ; extra == 'apache-flink' - - apache-airflow-providers-apache-hdfs>=4.6.0 ; extra == 'apache-hdfs' - - apache-airflow-providers-apache-hive>=8.2.1 ; extra == 'apache-hive' - - apache-airflow-providers-apache-iceberg>=1.2.0 ; extra == 'apache-iceberg' - - apache-airflow-providers-apache-impala>=1.5.2 ; extra == 'apache-impala' - - apache-airflow-providers-apache-kafka>=1.6.1 ; extra == 'apache-kafka' - - apache-airflow-providers-apache-kylin>=3.8.0 ; extra == 'apache-kylin' - - apache-airflow-providers-apache-livy>=3.9.2 ; extra == 'apache-livy' - - apache-airflow-providers-apache-pig>=4.6.0 ; extra == 'apache-pig' - - apache-airflow-providers-apache-pinot>=4.5.1 ; extra == 'apache-pinot' - - apache-airflow-providers-apache-spark>=4.11.1 ; extra == 'apache-spark' - - apache-airflow-providers-apache-hdfs ; extra == 'apache-webhdfs' - - apache-airflow-providers-apprise>=1.4.1 ; extra == 'apprise' - - apache-airflow-providers-arangodb>=2.7.0 ; extra == 'arangodb' - - apache-airflow-providers-asana>=2.7.0 ; extra == 'asana' - - apache-airflow-core[async] ; extra == 'async' - - apache-airflow-providers-atlassian-jira>=2.7.1 ; extra == 'atlassian-jira' - - apache-airflow-providers-celery>=3.8.3 ; extra == 'celery' - - apache-airflow-providers-cloudant>=4.0.1 ; extra == 'cloudant' - - cloudpickle>=2.2.1 ; extra == 'cloudpickle' - - apache-airflow-providers-cncf-kubernetes>=9.0.0 ; extra == 'cncf-kubernetes' - - apache-airflow-providers-cohere>=1.4.0 ; extra == 'cohere' - - apache-airflow-providers-common-compat>=1.2.1 ; extra == 'common-compat' - - apache-airflow-providers-common-io>=1.4.2 ; extra == 'common-io' - - apache-airflow-providers-common-messaging>=1.0.1 ; extra == 'common-messaging' - - apache-airflow-providers-common-sql>=1.18.0 ; extra == 'common-sql' - - apache-airflow-providers-databricks>=6.11.0 ; extra == 'databricks' - - apache-airflow-providers-datadog>=3.8.0 ; extra == 'datadog' - - apache-airflow-providers-dbt-cloud>=3.11.0 ; extra == 'dbt-cloud' - - apache-airflow-providers-dingding>=3.7.0 ; extra == 'dingding' - - apache-airflow-providers-discord>=3.9.0 ; extra == 'discord' - - apache-airflow-providers-docker>=3.14.1 ; extra == 'docker' - - apache-airflow-providers-edge3>=1.0.0 ; extra == 'edge3' - - apache-airflow-providers-elasticsearch>=5.5.2 ; extra == 'elasticsearch' - - apache-airflow-providers-exasol>=4.6.1 ; extra == 'exasol' - - apache-airflow-providers-fab>=2.2.0 ; extra == 'fab' - - apache-airflow-providers-facebook>=3.7.0 ; extra == 'facebook' - - apache-airflow-providers-ftp>=3.12.0 ; extra == 'ftp' - - apache-airflow-providers-git>=0.0.2 ; extra == 'git' - - apache-airflow-providers-github>=2.8.0 ; extra == 'github' - - apache-airflow-providers-fab ; extra == 'github-enterprise' - - authlib>=1.0.0 ; extra == 'github-enterprise' - - apache-airflow-providers-google>=10.24.0 ; extra == 'google' - - apache-airflow-providers-fab ; extra == 'google-auth' - - authlib>=1.0.0 ; extra == 'google-auth' - - apache-airflow-core[graphviz] ; extra == 'graphviz' - - apache-airflow-providers-grpc>=3.7.0 ; extra == 'grpc' - - apache-airflow-providers-hashicorp>=4.0.0 ; extra == 'hashicorp' - - apache-airflow-providers-http>=4.13.2 ; extra == 'http' - - apache-airflow-providers-imap>=3.8.0 ; extra == 'imap' - - apache-airflow-providers-influxdb>=2.8.0 ; extra == 'influxdb' - - apache-airflow-providers-jdbc>=4.5.2 ; extra == 'jdbc' - - apache-airflow-providers-jenkins>=3.7.2 ; extra == 'jenkins' - - apache-airflow-core[kerberos] ; extra == 'kerberos' - - python-ldap>=3.4.4 ; extra == 'ldap' - - apache-airflow-providers-microsoft-azure>=10.5.1 ; extra == 'microsoft-azure' - - apache-airflow-providers-microsoft-mssql>=3.9.2 ; extra == 'microsoft-mssql' - - apache-airflow-providers-microsoft-psrp>=3.0.0 ; extra == 'microsoft-psrp' - - apache-airflow-providers-microsoft-winrm>=3.6.1 ; extra == 'microsoft-winrm' - - apache-airflow-providers-mongo>=4.2.2 ; extra == 'mongo' - - apache-airflow-providers-mysql>=5.7.2 ; extra == 'mysql' - - apache-airflow-providers-neo4j>=3.8.0 ; extra == 'neo4j' - - apache-airflow-providers-odbc>=4.8.0 ; extra == 'odbc' - - apache-airflow-providers-openai>=1.5.0 ; extra == 'openai' - - apache-airflow-providers-openfaas>=3.7.0 ; extra == 'openfaas' - - apache-airflow-providers-openlineage>=2.1.3 ; extra == 'openlineage' - - apache-airflow-providers-opensearch>=1.5.0 ; extra == 'opensearch' - - apache-airflow-providers-opsgenie>=5.8.0 ; extra == 'opsgenie' - - apache-airflow-providers-oracle>=3.12.0 ; extra == 'oracle' - - apache-airflow-core[otel] ; extra == 'otel' - - apache-airflow-providers-pagerduty>=3.8.1 ; extra == 'pagerduty' - - apache-airflow-providers-common-sql[pandas] ; extra == 'pandas' - - apache-airflow-providers-papermill>=3.8.2 ; extra == 'papermill' - - apache-airflow-providers-pgvector>=1.4.0 ; extra == 'pgvector' - - apache-airflow-providers-pinecone>=2.1.1 ; extra == 'pinecone' - - apache-airflow-providers-common-sql[polars] ; extra == 'polars' - - apache-airflow-providers-postgres>=5.13.1 ; extra == 'postgres' - - apache-airflow-providers-presto>=5.7.0 ; extra == 'presto' - - apache-airflow-providers-qdrant>=1.3.0 ; extra == 'qdrant' - - amqp>=5.2.0 ; extra == 'rabbitmq' - - apache-airflow-providers-redis>=4.0.0 ; extra == 'redis' - - apache-airflow-providers-amazon[s3fs] ; extra == 's3fs' - - apache-airflow-providers-salesforce>=5.9.0 ; extra == 'salesforce' - - apache-airflow-providers-samba>=4.9.0 ; extra == 'samba' - - apache-airflow-providers-segment>=3.7.0 ; extra == 'segment' - - apache-airflow-providers-sendgrid>=4.0.0 ; extra == 'sendgrid' - - apache-airflow-core[sentry] ; extra == 'sentry' - - apache-airflow-providers-sftp>=5.0.0 ; extra == 'sftp' - - apache-airflow-providers-singularity>=3.7.0 ; extra == 'singularity' - - apache-airflow-providers-slack>=8.9.1 ; extra == 'slack' - - apache-airflow-providers-smtp>=1.8.1 ; extra == 'smtp' - - apache-airflow-providers-snowflake>=5.8.0 ; extra == 'snowflake' - - apache-airflow-providers-sqlite>=3.9.1 ; extra == 'sqlite' - - apache-airflow-providers-ssh>=3.14.0 ; extra == 'ssh' - - apache-airflow-providers-standard>=0.0.1 ; extra == 'standard' - - apache-airflow-core[statsd] ; extra == 'statsd' - - apache-airflow-providers-tableau>=5.0.0 ; extra == 'tableau' - - apache-airflow-providers-telegram>=4.7.0 ; extra == 'telegram' - - apache-airflow-providers-teradata>=2.6.1 ; extra == 'teradata' - - apache-airflow-providers-trino>=5.8.1 ; extra == 'trino' - - uv>=0.7.8 ; extra == 'uv' - - apache-airflow-providers-vertica>=3.9.1 ; extra == 'vertica' - - apache-airflow-providers-weaviate>=3.0.0 ; extra == 'weaviate' - - apache-airflow-providers-yandex>=4.0.0 ; extra == 'yandex' - - apache-airflow-providers-ydb>=1.4.0 ; extra == 'ydb' - - apache-airflow-providers-zendesk>=4.9.0 ; extra == 'zendesk' - requires_python: ~=3.9,<3.13 -- pypi: https://files.pythonhosted.org/packages/7b/fe/6efbbb6f07fd4031d19a2894d51ca6210cc5ae9365e21e4e5d92817bef63/apache_airflow_core-3.0.2-py3-none-any.whl - name: apache-airflow-core - version: 3.0.2 - sha256: 13b93d116889521e7e176cfe28fd7b36326dea9a4bae05e56738b86e1dfce4ad - requires_dist: - - a2wsgi>=1.10.8 - - aiosqlite>=0.20.0 - - alembic>=1.13.1,<2.0 - - apache-airflow-providers-common-compat>=1.6.0 - - apache-airflow-providers-common-io>=1.5.3 - - apache-airflow-providers-common-sql>=1.26.0 - - apache-airflow-providers-smtp>=2.0.2 - - apache-airflow-providers-standard>=0.4.0 - - apache-airflow-task-sdk>=1.0.2,<1.1.0 - - argcomplete>=1.10 - - asgiref>=2.3.0 - - attrs>=22.1.0,!=25.2.0 - - cadwyn>=5.2.1 - - colorlog>=6.8.2 - - cron-descriptor>=1.2.24 - - croniter>=2.0.2 - - cryptography>=41.0.0 - - deprecated>=1.2.13 - - dill>=0.2.2 - - eval-type-backport>=0.2.0 ; python_full_version < '3.10' - - fastapi[standard]>=0.115.0,!=0.115.10 - - flask>=2.1.1 - - gunicorn>=20.1.0 - - httpx>=0.25.0 - - importlib-metadata>=6.5 ; python_full_version < '3.12' - - importlib-metadata>=7.0 ; python_full_version >= '3.12' - - itsdangerous>=2.0 - - jinja2>=3.1.5 - - jsonschema>=4.19.1 - - lazy-object-proxy>=1.2.0 - - libcst>=1.1.0 - - linkify-it-py>=2.0.0 - - lockfile>=0.12.2 - - methodtools>=0.4.7 - - opentelemetry-api>=1.26.0 - - opentelemetry-exporter-otlp>=1.26.0 - - packaging>=23.2 - - pathspec>=0.9.0 - - pendulum>=2.1.2,<4.0 ; python_full_version < '3.12' - - pendulum>=3.0.0,<4.0 ; python_full_version >= '3.12' - - pluggy>=1.5.0 - - psutil>=5.8.0 - - pydantic>=2.11.0 - - pygments>=2.0.1,!=2.19.0 - - pyjwt>=2.10.0 - - python-daemon>=3.0.0 - - python-dateutil>=2.7.0 - - python-slugify>=5.0 - - requests>=2.31.0,<3 - - rich-argparse>=1.0.0 - - rich>=13.6.0 - - setproctitle>=1.3.3 - - sqlalchemy-jsonfield>=1.0 - - sqlalchemy-utils>=0.41.2 - - sqlalchemy[asyncio]>=1.4.49,<2.0 - - svcs>=25.1.0 - - tabulate>=0.9.0 - - tenacity>=8.0.0,!=8.2.0 - - termcolor>=3.0.0 - - typing-extensions!=4.14.0 - - universal-pathlib>=0.2.2,!=0.2.4 - - uuid6>=2024.7.10 - - blinker>=1.1 ; extra == 'all' - - graphviz>=0.12 ; sys_platform != 'darwin' and extra == 'all' - - opentelemetry-exporter-prometheus>=0.47b0 ; extra == 'all' - - pykerberos>=1.1.13 ; extra == 'all' - - requests-kerberos>=0.14.0 ; extra == 'all' - - sentry-sdk>=1.32.0,!=1.33.0 ; extra == 'all' - - statsd>=3.3.0 ; extra == 'all' - - thrift-sasl>=0.4.2 ; extra == 'all' - - eventlet>=0.37.0 ; extra == 'async' - - gevent>=24.2.1 ; extra == 'async' - - greenlet>=0.4.9 ; extra == 'async' - - graphviz>=0.12 ; sys_platform != 'darwin' and extra == 'graphviz' - - pykerberos>=1.1.13 ; extra == 'kerberos' - - requests-kerberos>=0.14.0 ; extra == 'kerberos' - - thrift-sasl>=0.4.2 ; extra == 'kerberos' - - opentelemetry-exporter-prometheus>=0.47b0 ; extra == 'otel' - - blinker>=1.1 ; extra == 'sentry' - - sentry-sdk>=1.32.0,!=1.33.0 ; extra == 'sentry' - - statsd>=3.3.0 ; extra == 'statsd' - requires_python: ~=3.9,<3.13 -- pypi: https://files.pythonhosted.org/packages/9d/06/5705308c34a368f1146f4920945f620f3b69ba82fa52ea34464e3a9f74ab/apache_airflow_providers_common_compat-1.7.2-py3-none-any.whl - name: apache-airflow-providers-common-compat - version: 1.7.2 - sha256: b57398bb26f0afe0c80c8ffe4d0f36496ac367cdbda14ff0312a95f09a6f936c - requires_dist: - - apache-airflow>=2.10.0 - - apache-airflow-providers-openlineage ; extra == 'openlineage' - - apache-airflow-providers-standard ; extra == 'standard' - requires_python: ~=3.10 -- pypi: https://files.pythonhosted.org/packages/e7/ef/b1e3503c2d8e9b1e9e351315426f5d94a5cd3a2cb344b74f3cbdbf0e2b6f/apache_airflow_providers_common_io-1.6.1-py3-none-any.whl - name: apache-airflow-providers-common-io - version: 1.6.1 - sha256: 54590eb60216d2a0beb13a7dc2777fabdc815f947b5ab387f097f492f4a3f317 - requires_dist: - - apache-airflow>=2.10.0 - - apache-airflow-providers-common-compat ; extra == 'common-compat' - - apache-airflow-providers-openlineage ; extra == 'openlineage' - requires_python: ~=3.10 -- pypi: https://files.pythonhosted.org/packages/07/07/5dc81b135b000620bde3466734e21f7a2c2ad9e8f4f0a559de8879f21334/apache_airflow_providers_common_sql-1.27.3-py3-none-any.whl - name: apache-airflow-providers-common-sql - version: 1.27.3 - sha256: 9e796b6a2f932a24c8ad23d8d357a8533365bed333cde5f8fd07d709ab2762ca - requires_dist: - - apache-airflow>=2.10.0 - - sqlparse>=0.5.1 - - more-itertools>=9.0.0 - - methodtools>=0.4.7 - - apache-airflow-providers-openlineage ; extra == 'openlineage' - - pandas>=2.1.2 ; python_full_version < '3.13' and extra == 'pandas' - - pandas>=2.2.3 ; python_full_version >= '3.13' and extra == 'pandas' - - polars>=1.26.0 ; extra == 'polars' - requires_python: ~=3.10 -- pypi: https://files.pythonhosted.org/packages/64/e9/a75c7cb806f054764454686651375c2f99aeabbe90cc2fc7d37666d93dbf/apache_airflow_providers_smtp-2.1.1-py3-none-any.whl - name: apache-airflow-providers-smtp - version: 2.1.1 - sha256: 66d1e69e3ab299611b41b1e16fd44b444d53fcd7727dccf44515be1b141b246a - requires_dist: - - apache-airflow>=2.10.0 - - apache-airflow-providers-common-compat>=1.6.1 - requires_python: ~=3.10 -- pypi: https://files.pythonhosted.org/packages/08/0c/5893b77b5b5fae795cc47ba67e33ae28ffae0b4d3b70f028f1e35d99f5ad/apache_airflow_providers_standard-1.4.1-py3-none-any.whl - name: apache-airflow-providers-standard - version: 1.4.1 - sha256: 44a22b9c0d892ae3fd4e4c4dc108f79575f254c9b64645223b99528db4d0e6af - requires_dist: - - apache-airflow>=2.10.0 - requires_python: ~=3.10 -- pypi: https://files.pythonhosted.org/packages/b0/90/b170b78a686ec5af2525f96df99a946c023483102ecd11a8d1cbbd1a7b66/apache_airflow_task_sdk-1.0.2-py3-none-any.whl - name: apache-airflow-task-sdk - version: 1.0.2 - sha256: 6f477a45131bb0778ac1ff4461498e297384576f03e828ec27bb89803d583d2f - requires_dist: - - aiologic>=0.14.0 - - apache-airflow-core>=3.0.2,<3.1.0 - - attrs>=24.2.0,!=25.2.0 - - fsspec>=2023.10.0 - - httpx>=0.27.0 - - jinja2>=3.1.5 - - methodtools>=0.4.7 - - msgspec>=0.19.0 - - pendulum>=2.1.2,<4.0 ; python_full_version < '3.12' - - pendulum>=3.0.0,<4.0 ; python_full_version >= '3.12' - - psutil>=6.1.0 - - python-dateutil>=2.7.0 - - retryhttp>=1.2.0,!=1.3.0 - - structlog>=25.4.0 - requires_python: '>=3.9,<3.13' -- pypi: https://files.pythonhosted.org/packages/31/da/e42d7a9d8dd33fa775f467e4028a47936da2f01e4b0e561f9ba0d74cb0ca/argcomplete-3.6.2-py3-none-any.whl - name: argcomplete - version: 3.6.2 - sha256: 65b3133a29ad53fb42c48cf5114752c7ab66c1c38544fdf6460f450c09b42591 - requires_dist: - - coverage ; extra == 'test' - - mypy ; extra == 'test' - - pexpect ; extra == 'test' - - ruff ; extra == 'test' - - wheel ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - name: argon2-cffi - version: 25.1.0 - sha256: fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741 - requires_dist: - - argon2-cffi-bindings - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/ec/f7/378254e6dd7ae6f31fe40c8649eea7d4832a42243acaf0f1fff9083b2bed/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: argon2-cffi-bindings - version: 21.2.0 - sha256: b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae - requires_dist: - - cffi>=1.0.1 - - pytest ; extra == 'dev' - - cogapp ; extra == 'dev' - - pre-commit ; extra == 'dev' - - wheel ; extra == 'dev' - - pytest ; extra == 'tests' - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl - name: arrow - version: 1.3.0 - sha256: c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80 - requires_dist: - - python-dateutil>=2.7.0 - - types-python-dateutil>=2.8.10 - - doc8 ; extra == 'doc' - - sphinx>=7.0.0 ; extra == 'doc' - - sphinx-autobuild ; extra == 'doc' - - sphinx-autodoc-typehints ; extra == 'doc' - - sphinx-rtd-theme>=1.3.0 ; extra == 'doc' - - dateparser==1.* ; extra == 'test' - - pre-commit ; extra == 'test' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-mock ; extra == 'test' - - pytz==2021.1 ; extra == 'test' - - simplejson==3.* ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/7c/3c/0464dcada90d5da0e71018c04a140ad6349558afb30b3051b4264cc5b965/asgiref-3.9.1-py3-none-any.whl - name: asgiref - version: 3.9.1 - sha256: f3bba7092a48005b5f5bacd747d36ee4a5a61f4a269a6df590b43144355ebd2c - requires_dist: - - typing-extensions>=4 ; python_full_version < '3.11' - - pytest ; extra == 'tests' - - pytest-asyncio ; extra == 'tests' - - mypy>=1.14.0 ; extra == 'tests' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl - name: asttokens - version: 3.0.0 - sha256: e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2 - requires_dist: - - astroid>=2,<4 ; extra == 'astroid' - - astroid>=2,<4 ; extra == 'test' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-xdist ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-py3-none-any.whl - name: async-lru - version: 2.0.5 - sha256: ab95404d8d2605310d345932697371a5f40def0487c03d6d0ad9138de52c9943 - requires_dist: - - typing-extensions>=4.0.0 ; python_full_version < '3.11' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl - name: attrs - version: 25.3.0 - sha256: 427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3 - requires_dist: - - cloudpickle ; platform_python_implementation == 'CPython' and extra == 'benchmark' - - hypothesis ; extra == 'benchmark' - - mypy>=1.11.1 ; python_full_version >= '3.10' and platform_python_implementation == 'CPython' and extra == 'benchmark' - - pympler ; extra == 'benchmark' - - pytest-codspeed ; extra == 'benchmark' - - pytest-mypy-plugins ; python_full_version >= '3.10' and platform_python_implementation == 'CPython' and extra == 'benchmark' - - pytest-xdist[psutil] ; extra == 'benchmark' - - pytest>=4.3.0 ; extra == 'benchmark' - - cloudpickle ; platform_python_implementation == 'CPython' and extra == 'cov' - - coverage[toml]>=5.3 ; extra == 'cov' - - hypothesis ; extra == 'cov' - - mypy>=1.11.1 ; python_full_version >= '3.10' and platform_python_implementation == 'CPython' and extra == 'cov' - - pympler ; extra == 'cov' - - pytest-mypy-plugins ; python_full_version >= '3.10' and platform_python_implementation == 'CPython' and extra == 'cov' - - pytest-xdist[psutil] ; extra == 'cov' - - pytest>=4.3.0 ; extra == 'cov' - - cloudpickle ; platform_python_implementation == 'CPython' and extra == 'dev' - - hypothesis ; extra == 'dev' - - mypy>=1.11.1 ; python_full_version >= '3.10' and platform_python_implementation == 'CPython' and extra == 'dev' - - pre-commit-uv ; extra == 'dev' - - pympler ; extra == 'dev' - - pytest-mypy-plugins ; python_full_version >= '3.10' and platform_python_implementation == 'CPython' and extra == 'dev' - - pytest-xdist[psutil] ; extra == 'dev' - - pytest>=4.3.0 ; extra == 'dev' - - cogapp ; extra == 'docs' - - furo ; extra == 'docs' - - myst-parser ; extra == 'docs' - - sphinx ; extra == 'docs' - - sphinx-notfound-page ; extra == 'docs' - - sphinxcontrib-towncrier ; extra == 'docs' - - towncrier ; extra == 'docs' - - cloudpickle ; platform_python_implementation == 'CPython' and extra == 'tests' - - hypothesis ; extra == 'tests' - - mypy>=1.11.1 ; python_full_version >= '3.10' and platform_python_implementation == 'CPython' and extra == 'tests' - - pympler ; extra == 'tests' - - pytest-mypy-plugins ; python_full_version >= '3.10' and platform_python_implementation == 'CPython' and extra == 'tests' - - pytest-xdist[psutil] ; extra == 'tests' - - pytest>=4.3.0 ; extra == 'tests' - - mypy>=1.11.1 ; python_full_version >= '3.10' and platform_python_implementation == 'CPython' and extra == 'tests-mypy' - - pytest-mypy-plugins ; python_full_version >= '3.10' and platform_python_implementation == 'CPython' and extra == 'tests-mypy' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl - name: babel - version: 2.17.0 - sha256: 4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 - requires_dist: - - pytz>=2015.7 ; python_full_version < '3.9' - - tzdata ; sys_platform == 'win32' and extra == 'dev' - - backports-zoneinfo ; python_full_version < '3.9' and extra == 'dev' - - freezegun~=1.0 ; extra == 'dev' - - jinja2>=3.0 ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - pytest>=6.0 ; extra == 'dev' - - pytz ; extra == 'dev' - - setuptools ; extra == 'dev' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl - name: beautifulsoup4 - version: 4.13.4 - sha256: 9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b - requires_dist: - - soupsieve>1.2 - - typing-extensions>=4.0.0 - - cchardet ; extra == 'cchardet' - - chardet ; extra == 'chardet' - - charset-normalizer ; extra == 'charset-normalizer' - - html5lib ; extra == 'html5lib' - - lxml ; extra == 'lxml' - requires_python: '>=3.7.0' -- pypi: https://files.pythonhosted.org/packages/fc/55/96142937f66150805c25c4d0f31ee4132fd33497753400734f9dfdcbdc66/bleach-6.2.0-py3-none-any.whl - name: bleach - version: 6.2.0 - sha256: 117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e - requires_dist: - - webencodings - - tinycss2>=1.1.0,<1.5 ; extra == 'css' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - name: blinker - version: 1.9.0 - sha256: ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - sha256: 5ced96500d945fb286c9c838e54fa759aa04a7129c59800f0846b4335cee770d - md5: 62ee74e96c5ebb0af99386de58cf9553 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - license: bzip2-1.0.6 - license_family: BSD - purls: [] - size: 252783 - timestamp: 1720974456583 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda - sha256: 29defbd83c7829788358678ec996adeee252fa4d4274b7cd386c1ed73d2b201e - md5: d16c90324aef024877d8713c0b7fea5b - depends: - - __unix - license: ISC - purls: [] - size: 155658 - timestamp: 1752482350666 -- pypi: https://files.pythonhosted.org/packages/f3/67/442922a6758c1059907e3030e1a978a11533d08ac459ccd3cd255596b316/cadwyn-5.4.4-py3-none-any.whl - name: cadwyn - version: 5.4.4 - sha256: e466b5769dcc6be13866d366cf0cd670e79ecced387de33726d50b19e3f2405d - requires_dist: - - backports-strenum>=1.3.1,<2 ; python_full_version < '3.11' - - fastapi>=0.112.4 - - jinja2>=3.1.2 - - pydantic>=2.11.0 - - starlette>=0.30.0 - - typing-extensions>=4.8.0 - - typing-inspection>=0.4.0 - - fastapi[standard]>=0.112.3 ; extra == 'standard' - - typer>=0.7.0 ; extra == 'standard' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/4f/52/34c6cf5bb9285074dc3531c437b3919e825d976fde097a7a73f79e726d03/certifi-2025.7.14-py3-none-any.whl - name: certifi - version: 2025.7.14 - sha256: 6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: cffi - version: 1.17.1 - sha256: b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 - requires_dist: - - pycparser - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: charset-normalizer - version: 3.4.2 - sha256: 4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl - name: click - version: 8.2.1 - sha256: 61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b - requires_dist: - - colorama ; sys_platform == 'win32' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/e3/51/9b208e85196941db2f0654ad0357ca6388ab3ed67efdbfc799f35d1f83aa/colorlog-6.9.0-py3-none-any.whl - name: colorlog - version: 6.9.0 - sha256: 5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff - requires_dist: - - colorama ; sys_platform == 'win32' - - black ; extra == 'development' - - flake8 ; extra == 'development' - - mypy ; extra == 'development' - - pytest ; extra == 'development' - - types-colorama ; extra == 'development' - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/e6/75/49e5bfe642f71f272236b5b2d2691cf915a7283cc0ceda56357b61daa538/comm-0.2.2-py3-none-any.whl - name: comm - version: 0.2.2 - sha256: e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3 - requires_dist: - - traitlets>=4 - - pytest ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/79/13/13576941bf7cf95026abae43d8427c812c0054408212bf8ed490eda846b0/crc32c-2.7.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: crc32c - version: 2.7.1 - sha256: c02a3bd67dea95cdb25844aaf44ca2e1b0c1fd70b287ad08c874a95ef4bb38db - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/88/20/2cfe598ead23a715a00beb716477cfddd3e5948cf203c372d02221e5b0c6/cron_descriptor-1.4.5-py3-none-any.whl - name: cron-descriptor - version: 1.4.5 - sha256: 736b3ae9d1a99bc3dbfc5b55b5e6e7c12031e7ba5de716625772f8b02dcd6013 - requires_dist: - - polib ; extra == 'dev' -- pypi: https://files.pythonhosted.org/packages/07/4b/290b4c3efd6417a8b0c284896de19b1d5855e6dbdb97d2a35e68fa42de85/croniter-6.0.0-py2.py3-none-any.whl - name: croniter - version: 6.0.0 - sha256: 2f878c3856f17896979b2a4379ba1f09c83e374931ea15cc835c5dd2eee9b368 - requires_dist: - - python-dateutil - - pytz>2021.1 - requires_python: '>=2.6,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- pypi: https://files.pythonhosted.org/packages/ec/ef/3333295ed58d900a13c92806b67e62f27876845a9a908c939f040887cca9/cryptography-45.0.5-cp311-abi3-manylinux_2_28_x86_64.whl - name: cryptography - version: 45.0.5 - sha256: dd420e577921c8c2d31289536c386aaa30140b473835e97f83bc71ea9d2baf2d - requires_dist: - - cffi>=1.14 ; platform_python_implementation != 'PyPy' - - bcrypt>=3.1.5 ; extra == 'ssh' - - nox>=2024.4.15 ; extra == 'nox' - - nox[uv]>=2024.3.2 ; python_full_version >= '3.8' and extra == 'nox' - - cryptography-vectors==45.0.5 ; extra == 'test' - - pytest>=7.4.0 ; extra == 'test' - - pytest-benchmark>=4.0 ; extra == 'test' - - pytest-cov>=2.10.1 ; extra == 'test' - - pytest-xdist>=3.5.0 ; extra == 'test' - - pretend>=0.7 ; extra == 'test' - - certifi>=2024 ; extra == 'test' - - pytest-randomly ; extra == 'test-randomorder' - - sphinx>=5.3.0 ; extra == 'docs' - - sphinx-rtd-theme>=3.0.0 ; python_full_version >= '3.8' and extra == 'docs' - - sphinx-inline-tabs ; python_full_version >= '3.8' and extra == 'docs' - - pyenchant>=3 ; extra == 'docstest' - - readme-renderer>=30.0 ; extra == 'docstest' - - sphinxcontrib-spelling>=7.3.1 ; extra == 'docstest' - - build>=1.0.0 ; extra == 'sdist' - - ruff>=0.3.6 ; extra == 'pep8test' - - mypy>=1.4 ; extra == 'pep8test' - - check-sdist ; python_full_version >= '3.8' and extra == 'pep8test' - - click>=8.0.1 ; extra == 'pep8test' - requires_python: '>=3.7,!=3.9.0,!=3.9.1' -- pypi: https://files.pythonhosted.org/packages/99/8d/7f6ef1097e7fecf26b4ef72338d08e41644a41b7ee958a19f494ffcffc29/debugpy-1.8.15-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: debugpy - version: 1.8.15 - sha256: 047a493ca93c85ccede1dbbaf4e66816794bdc214213dde41a9a61e42d27f8fc - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - name: decorator - version: 5.2.1 - sha256: d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - name: defusedxml - version: 0.7.1 - sha256: a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' -- pypi: https://files.pythonhosted.org/packages/6e/c6/ac0b6c1e2d138f1002bcf799d330bd6d85084fece321e662a14223794041/Deprecated-1.2.18-py2.py3-none-any.whl - name: deprecated - version: 1.2.18 - sha256: bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec - requires_dist: - - wrapt>=1.10,<2 - - tox ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - bump2version<1 ; extra == 'dev' - - setuptools ; python_full_version >= '3.12' and extra == 'dev' - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl - name: dill - version: 0.4.0 - sha256: 44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049 - requires_dist: - - objgraph>=1.7.2 ; extra == 'graph' - - gprof2dot>=2022.7.29 ; extra == 'profile' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl - name: dnspython - version: 2.7.0 - sha256: b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86 - requires_dist: - - black>=23.1.0 ; extra == 'dev' - - coverage>=7.0 ; extra == 'dev' - - flake8>=7 ; extra == 'dev' - - hypercorn>=0.16.0 ; extra == 'dev' - - mypy>=1.8 ; extra == 'dev' - - pylint>=3 ; extra == 'dev' - - pytest-cov>=4.1.0 ; extra == 'dev' - - pytest>=7.4 ; extra == 'dev' - - quart-trio>=0.11.0 ; extra == 'dev' - - sphinx-rtd-theme>=2.0.0 ; extra == 'dev' - - sphinx>=7.2.0 ; extra == 'dev' - - twine>=4.0.0 ; extra == 'dev' - - wheel>=0.42.0 ; extra == 'dev' - - cryptography>=43 ; extra == 'dnssec' - - h2>=4.1.0 ; extra == 'doh' - - httpcore>=1.0.0 ; extra == 'doh' - - httpx>=0.26.0 ; extra == 'doh' - - aioquic>=1.0.0 ; extra == 'doq' - - idna>=3.7 ; extra == 'idna' - - trio>=0.23 ; extra == 'trio' - - wmi>=1.5.1 ; extra == 'wmi' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl - name: donfig - version: 0.8.1.post1 - sha256: 2a3175ce74a06109ff9307d90a230f81215cbac9a751f4d1c6194644b8204f9d - requires_dist: - - pyyaml - - sphinx>=4.0.0 ; extra == 'docs' - - numpydoc ; extra == 'docs' - - pytest ; extra == 'docs' - - cloudpickle ; extra == 'docs' - - pytest ; extra == 'test' - - cloudpickle ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl - name: email-validator - version: 2.2.0 - sha256: 561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631 - requires_dist: - - dnspython>=2.0.0 - - idna>=2.0.0 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl - name: executing - version: 2.2.0 - sha256: 11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa - requires_dist: - - asttokens>=2.1.0 ; extra == 'tests' - - ipython ; extra == 'tests' - - pytest ; extra == 'tests' - - coverage ; extra == 'tests' - - coverage-enable-subprocess ; extra == 'tests' - - littleutils ; extra == 'tests' - - rich ; python_full_version >= '3.11' and extra == 'tests' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/e5/47/d63c60f59a59467fda0f93f46335c9d18526d7071f025cb5b89d5353ea42/fastapi-0.116.1-py3-none-any.whl - name: fastapi - version: 0.116.1 - sha256: c46ac7c312df840f0c9e220f7964bada936781bc4e2e6eb71f1c4d7553786565 - requires_dist: - - starlette>=0.40.0,<0.48.0 - - pydantic>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0 - - typing-extensions>=4.8.0 - - fastapi-cli[standard]>=0.0.8 ; extra == 'standard' - - httpx>=0.23.0 ; extra == 'standard' - - jinja2>=3.1.5 ; extra == 'standard' - - python-multipart>=0.0.18 ; extra == 'standard' - - email-validator>=2.0.0 ; extra == 'standard' - - uvicorn[standard]>=0.12.0 ; extra == 'standard' - - fastapi-cli[standard-no-fastapi-cloud-cli]>=0.0.8 ; extra == 'standard-no-fastapi-cloud-cli' - - httpx>=0.23.0 ; extra == 'standard-no-fastapi-cloud-cli' - - jinja2>=3.1.5 ; extra == 'standard-no-fastapi-cloud-cli' - - python-multipart>=0.0.18 ; extra == 'standard-no-fastapi-cloud-cli' - - email-validator>=2.0.0 ; extra == 'standard-no-fastapi-cloud-cli' - - uvicorn[standard]>=0.12.0 ; extra == 'standard-no-fastapi-cloud-cli' - - fastapi-cli[standard]>=0.0.8 ; extra == 'all' - - httpx>=0.23.0 ; extra == 'all' - - jinja2>=3.1.5 ; extra == 'all' - - python-multipart>=0.0.18 ; extra == 'all' - - itsdangerous>=1.1.0 ; extra == 'all' - - pyyaml>=5.3.1 ; extra == 'all' - - ujson>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0 ; extra == 'all' - - orjson>=3.2.1 ; extra == 'all' - - email-validator>=2.0.0 ; extra == 'all' - - uvicorn[standard]>=0.12.0 ; extra == 'all' - - pydantic-settings>=2.0.0 ; extra == 'all' - - pydantic-extra-types>=2.0.0 ; extra == 'all' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/e0/3f/6ad3103c5f59208baf4c798526daea6a74085bb35d1c161c501863470476/fastapi_cli-0.0.8-py3-none-any.whl - name: fastapi-cli - version: 0.0.8 - sha256: 0ea95d882c85b9219a75a65ab27e8da17dac02873e456850fa0a726e96e985eb - requires_dist: - - typer>=0.15.1 - - uvicorn[standard]>=0.15.0 - - rich-toolkit>=0.14.8 - - uvicorn[standard]>=0.15.0 ; extra == 'standard' - - fastapi-cloud-cli>=0.1.1 ; extra == 'standard' - - uvicorn[standard]>=0.15.0 ; extra == 'standard-no-fastapi-cloud-cli' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/42/cf/8635cd778b7d89714325b967a28c05865a2b6cab4c0b4b30561df4704f24/fastapi_cloud_cli-0.1.4-py3-none-any.whl - name: fastapi-cloud-cli - version: 0.1.4 - sha256: 1db1ba757aa46a16a5e5dacf7cddc137ca0a3c42f65dba2b1cc6a8f24c41be42 - requires_dist: - - typer>=0.12.3 - - uvicorn[standard]>=0.15.0 - - rignore>=0.5.1 - - httpx>=0.27.0 - - rich-toolkit>=0.14.5 - - pydantic[email]>=1.6.1 - - sentry-sdk>=2.20.0 - - uvicorn[standard]>=0.15.0 ; extra == 'standard' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/90/2b/0817a2b257fe88725c25589d89aec060581aabf668707a8d03b2e9e0cb2a/fastjsonschema-2.21.1-py3-none-any.whl - name: fastjsonschema - version: 2.21.1 - sha256: c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667 - requires_dist: - - colorama ; extra == 'devel' - - jsonschema ; extra == 'devel' - - json-spec ; extra == 'devel' - - pylint ; extra == 'devel' - - pytest ; extra == 'devel' - - pytest-benchmark ; extra == 'devel' - - pytest-cache ; extra == 'devel' - - validictory ; extra == 'devel' -- pypi: https://files.pythonhosted.org/packages/3d/68/9d4508e893976286d2ead7f8f571314af6c2037af34853a30fd769c02e9d/flask-3.1.1-py3-none-any.whl - name: flask - version: 3.1.1 - sha256: 07aae2bb5eaf77993ef57e357491839f5fd9f4dc281593a81a9e4d79a24f295c - requires_dist: - - blinker>=1.9.0 - - click>=8.1.3 - - importlib-metadata>=3.6.0 ; python_full_version < '3.10' - - itsdangerous>=2.2.0 - - jinja2>=3.1.2 - - markupsafe>=2.1.1 - - werkzeug>=3.1.0 - - asgiref>=3.2 ; extra == 'async' - - python-dotenv ; extra == 'dotenv' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl - name: fqdn - version: 1.5.1 - sha256: 3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014 - requires_dist: - - cached-property>=1.3.0 ; python_full_version < '3.8' - requires_python: '>=2.7,!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,<4' -- pypi: https://files.pythonhosted.org/packages/2f/e0/014d5d9d7a4564cf1c40b5039bc882db69fd881111e03ab3657ac0b218e2/fsspec-2025.7.0-py3-none-any.whl - name: fsspec - version: 2025.7.0 - sha256: 8b012e39f63c7d5f10474de957f3ab793b47b45ae7d39f2fb735f8bbe25c0e21 - requires_dist: - - adlfs ; extra == 'abfs' - - adlfs ; extra == 'adl' - - pyarrow>=1 ; extra == 'arrow' - - dask ; extra == 'dask' - - distributed ; extra == 'dask' - - pre-commit ; extra == 'dev' - - ruff>=0.5 ; extra == 'dev' - - numpydoc ; extra == 'doc' - - sphinx ; extra == 'doc' - - sphinx-design ; extra == 'doc' - - sphinx-rtd-theme ; extra == 'doc' - - yarl ; extra == 'doc' - - dropbox ; extra == 'dropbox' - - dropboxdrivefs ; extra == 'dropbox' - - requests ; extra == 'dropbox' - - adlfs ; extra == 'full' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'full' - - dask ; extra == 'full' - - distributed ; extra == 'full' - - dropbox ; extra == 'full' - - dropboxdrivefs ; extra == 'full' - - fusepy ; extra == 'full' - - gcsfs ; extra == 'full' - - libarchive-c ; extra == 'full' - - ocifs ; extra == 'full' - - panel ; extra == 'full' - - paramiko ; extra == 'full' - - pyarrow>=1 ; extra == 'full' - - pygit2 ; extra == 'full' - - requests ; extra == 'full' - - s3fs ; extra == 'full' - - smbprotocol ; extra == 'full' - - tqdm ; extra == 'full' - - fusepy ; extra == 'fuse' - - gcsfs ; extra == 'gcs' - - pygit2 ; extra == 'git' - - requests ; extra == 'github' - - gcsfs ; extra == 'gs' - - panel ; extra == 'gui' - - pyarrow>=1 ; extra == 'hdfs' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'http' - - libarchive-c ; extra == 'libarchive' - - ocifs ; extra == 'oci' - - s3fs ; extra == 's3' - - paramiko ; extra == 'sftp' - - smbprotocol ; extra == 'smb' - - paramiko ; extra == 'ssh' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test' - - numpy ; extra == 'test' - - pytest ; extra == 'test' - - pytest-asyncio!=0.22.0 ; extra == 'test' - - pytest-benchmark ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-mock ; extra == 'test' - - pytest-recording ; extra == 'test' - - pytest-rerunfailures ; extra == 'test' - - requests ; extra == 'test' - - aiobotocore>=2.5.4,<3.0.0 ; extra == 'test-downstream' - - dask[dataframe,test] ; extra == 'test-downstream' - - moto[server]>4,<5 ; extra == 'test-downstream' - - pytest-timeout ; extra == 'test-downstream' - - xarray ; extra == 'test-downstream' - - adlfs ; extra == 'test-full' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test-full' - - cloudpickle ; extra == 'test-full' - - dask ; extra == 'test-full' - - distributed ; extra == 'test-full' - - dropbox ; extra == 'test-full' - - dropboxdrivefs ; extra == 'test-full' - - fastparquet ; extra == 'test-full' - - fusepy ; extra == 'test-full' - - gcsfs ; extra == 'test-full' - - jinja2 ; extra == 'test-full' - - kerchunk ; extra == 'test-full' - - libarchive-c ; extra == 'test-full' - - lz4 ; extra == 'test-full' - - notebook ; extra == 'test-full' - - numpy ; extra == 'test-full' - - ocifs ; extra == 'test-full' - - pandas ; extra == 'test-full' - - panel ; extra == 'test-full' - - paramiko ; extra == 'test-full' - - pyarrow ; extra == 'test-full' - - pyarrow>=1 ; extra == 'test-full' - - pyftpdlib ; extra == 'test-full' - - pygit2 ; extra == 'test-full' - - pytest ; extra == 'test-full' - - pytest-asyncio!=0.22.0 ; extra == 'test-full' - - pytest-benchmark ; extra == 'test-full' - - pytest-cov ; extra == 'test-full' - - pytest-mock ; extra == 'test-full' - - pytest-recording ; extra == 'test-full' - - pytest-rerunfailures ; extra == 'test-full' - - python-snappy ; extra == 'test-full' - - requests ; extra == 'test-full' - - smbprotocol ; extra == 'test-full' - - tqdm ; extra == 'test-full' - - urllib3 ; extra == 'test-full' - - zarr ; extra == 'test-full' - - zstandard ; python_full_version < '3.14' and extra == 'test-full' - - tqdm ; extra == 'tqdm' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/86/f1/62a193f0227cf15a920390abe675f386dec35f7ae3ffe6da582d3ade42c7/googleapis_common_protos-1.70.0-py3-none-any.whl - name: googleapis-common-protos - version: 1.70.0 - sha256: b8bfcca8c25a2bb253e0e0b0adaf8c00773e5e6af6fd92397576680b807e0fd8 - requires_dist: - - protobuf>=3.20.2,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0 - - grpcio>=1.44.0,<2.0.0 ; extra == 'grpc' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/f6/f6/c82ac1851c60851302d8581680573245c8fc300253fc1ff741ae74a6c24d/greenlet-3.2.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - name: greenlet - version: 3.2.3 - sha256: 706d016a03e78df129f68c4c9b4c4f963f7d73534e48a24f5f5a7101ed13dbbb - requires_dist: - - sphinx ; extra == 'docs' - - furo ; extra == 'docs' - - objgraph ; extra == 'test' - - psutil ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/6e/66/e8fe779b23b5a26d1b6949e5c70bc0a5fd08f61a6ec5ac7760d589229511/grpcio-1.73.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: grpcio - version: 1.73.1 - sha256: 83a6c2cce218e28f5040429835fa34a29319071079e3169f9543c3fbeff166d2 - requires_dist: - - grpcio-tools>=1.73.1 ; extra == 'protobuf' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/cb/7d/6dac2a6e1eba33ee43f318edbed4ff29151a49b5d37f080aad1e6469bca4/gunicorn-23.0.0-py3-none-any.whl - name: gunicorn - version: 23.0.0 - sha256: ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d - requires_dist: - - packaging - - importlib-metadata ; python_full_version < '3.8' - - eventlet>=0.24.1,!=0.36.0 ; extra == 'eventlet' - - gevent>=1.4.0 ; extra == 'gevent' - - setproctitle ; extra == 'setproctitle' - - gevent ; extra == 'testing' - - eventlet ; extra == 'testing' - - coverage ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - tornado>=0.2 ; extra == 'tornado' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - name: h11 - version: 0.16.0 - sha256: 63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - name: httpcore - version: 1.0.9 - sha256: 2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 - requires_dist: - - certifi - - h11>=0.16 - - anyio>=4.0,<5.0 ; extra == 'asyncio' - - h2>=3,<5 ; extra == 'http2' - - socksio==1.* ; extra == 'socks' - - trio>=0.22.0,<1.0 ; extra == 'trio' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/f7/d8/b644c44acc1368938317d76ac991c9bba1166311880bcc0ac297cb9d6bd7/httptools-0.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: httptools - version: 0.6.4 - sha256: 16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2 - requires_dist: - - cython>=0.29.24 ; extra == 'test' - requires_python: '>=3.8.0' -- pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - name: httpx - version: 0.28.1 - sha256: d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad - requires_dist: - - anyio - - certifi - - httpcore==1.* - - idna - - brotli ; platform_python_implementation == 'CPython' and extra == 'brotli' - - brotlicffi ; platform_python_implementation != 'CPython' and extra == 'brotli' - - click==8.* ; extra == 'cli' - - pygments==2.* ; extra == 'cli' - - rich>=10,<14 ; extra == 'cli' - - h2>=3,<5 ; extra == 'http2' - - socksio==1.* ; extra == 'socks' - - zstandard>=0.18.0 ; extra == 'zstd' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - sha256: 71e750d509f5fa3421087ba88ef9a7b9be11c53174af3aa4d06aff4c18b38e8e - md5: 8b189310083baabfb622af68fd9d3ae3 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 - license: MIT - license_family: MIT - purls: [] - size: 12129203 - timestamp: 1720853576813 -- pypi: https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl - name: idna - version: '3.10' - sha256: 946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 - requires_dist: - - ruff>=0.6.2 ; extra == 'all' - - mypy>=1.11.2 ; extra == 'all' - - pytest>=8.3.2 ; extra == 'all' - - flake8>=7.1.1 ; extra == 'all' - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl - name: importlib-metadata - version: 8.7.0 - sha256: e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd - requires_dist: - - zipp>=3.20 - - typing-extensions>=3.6.4 ; python_full_version < '3.8' - - pytest>=6,!=8.1.* ; extra == 'test' - - importlib-resources>=1.3 ; python_full_version < '3.9' and extra == 'test' - - packaging ; extra == 'test' - - pyfakefs ; extra == 'test' - - flufl-flake8 ; extra == 'test' - - pytest-perf>=0.9.2 ; extra == 'test' - - jaraco-test>=5.4 ; extra == 'test' - - sphinx>=3.5 ; extra == 'doc' - - jaraco-packaging>=9.3 ; extra == 'doc' - - rst-linker>=1.9 ; extra == 'doc' - - furo ; extra == 'doc' - - sphinx-lint ; extra == 'doc' - - jaraco-tidelift>=1.4 ; extra == 'doc' - - ipython ; extra == 'perf' - - pytest-checkdocs>=2.4 ; extra == 'check' - - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' - - pytest-cov ; extra == 'cover' - - pytest-enabler>=2.2 ; extra == 'enabler' - - pytest-mypy ; extra == 'type' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl - name: iniconfig - version: 2.1.0 - sha256: 9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/1f/3d/00813c3d9b46e3dcd88bd4530e0a3c63c0509e5d8c9eff34723ea243ab04/ipykernel-6.30.0-py3-none-any.whl - name: ipykernel - version: 6.30.0 - sha256: fd2936e55c4a1c2ee8b1e5fa6a372b8eecc0ab1338750dee76f48fa5cca1301e - requires_dist: - - appnope>=0.1.2 ; sys_platform == 'darwin' - - comm>=0.1.1 - - debugpy>=1.6.5 - - ipython>=7.23.1 - - jupyter-client>=8.0.0 - - jupyter-core>=4.12,!=5.0.* - - matplotlib-inline>=0.1 - - nest-asyncio>=1.4 - - packaging>=22 - - psutil>=5.7 - - pyzmq>=25 - - tornado>=6.2 - - traitlets>=5.4.0 - - coverage[toml] ; extra == 'cov' - - matplotlib ; extra == 'cov' - - pytest-cov ; extra == 'cov' - - trio ; extra == 'cov' - - intersphinx-registry ; extra == 'docs' - - myst-parser ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - sphinx ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - sphinxcontrib-github-alt ; extra == 'docs' - - sphinxcontrib-spelling ; extra == 'docs' - - trio ; extra == 'docs' - - pyqt5 ; extra == 'pyqt5' - - pyside6 ; extra == 'pyside6' - - flaky ; extra == 'test' - - ipyparallel ; extra == 'test' - - pre-commit ; extra == 'test' - - pytest-asyncio>=0.23.5 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest>=7.0,<9 ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/63/f8/0031ee2b906a15a33d6bfc12dd09c3dfa966b3cb5b284ecfb7549e6ac3c4/ipython-9.4.0-py3-none-any.whl - name: ipython - version: 9.4.0 - sha256: 25850f025a446d9b359e8d296ba175a36aedd32e83ca9b5060430fe16801f066 - requires_dist: - - colorama ; sys_platform == 'win32' - - decorator - - ipython-pygments-lexers - - jedi>=0.16 - - matplotlib-inline - - pexpect>4.3 ; sys_platform != 'emscripten' and sys_platform != 'win32' - - prompt-toolkit>=3.0.41,<3.1.0 - - pygments>=2.4.0 - - stack-data - - traitlets>=5.13.0 - - typing-extensions>=4.6 ; python_full_version < '3.12' - - black ; extra == 'black' - - docrepr ; extra == 'doc' - - exceptiongroup ; extra == 'doc' - - intersphinx-registry ; extra == 'doc' - - ipykernel ; extra == 'doc' - - ipython[test] ; extra == 'doc' - - matplotlib ; extra == 'doc' - - setuptools>=18.5 ; extra == 'doc' - - sphinx-toml==0.0.4 ; extra == 'doc' - - sphinx-rtd-theme ; extra == 'doc' - - sphinx>=1.3 ; extra == 'doc' - - typing-extensions ; extra == 'doc' - - pytest ; extra == 'test' - - pytest-asyncio<0.22 ; extra == 'test' - - testpath ; extra == 'test' - - packaging ; extra == 'test' - - ipython[test] ; extra == 'test-extra' - - curio ; extra == 'test-extra' - - jupyter-ai ; extra == 'test-extra' - - matplotlib!=3.2.0 ; extra == 'test-extra' - - nbformat ; extra == 'test-extra' - - nbclient ; extra == 'test-extra' - - ipykernel ; extra == 'test-extra' - - numpy>=1.23 ; extra == 'test-extra' - - pandas ; extra == 'test-extra' - - trio ; extra == 'test-extra' - - matplotlib ; extra == 'matplotlib' - - ipython[doc,matplotlib,test,test-extra] ; extra == 'all' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl - name: ipython-pygments-lexers - version: 1.1.1 - sha256: a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c - requires_dist: - - pygments - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/58/6a/9166369a2f092bd286d24e6307de555d63616e8ddb373ebad2b5635ca4cd/ipywidgets-8.1.7-py3-none-any.whl - name: ipywidgets - version: 8.1.7 - sha256: 764f2602d25471c213919b8a1997df04bef869251db4ca8efba1b76b1bd9f7bb - requires_dist: - - comm>=0.1.3 - - ipython>=6.1.0 - - traitlets>=4.3.1 - - widgetsnbextension~=4.0.14 - - jupyterlab-widgets~=3.0.15 - - jsonschema ; extra == 'test' - - ipykernel ; extra == 'test' - - pytest>=3.6.0 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytz ; extra == 'test' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl - name: isoduration - version: 20.11.0 - sha256: b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042 - requires_dist: - - arrow>=0.15.0 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/c1/11/114d0a5f4dabbdcedc1125dee0888514c3c3b16d3e9facad87ed96fad97c/isort-6.0.1-py3-none-any.whl - name: isort - version: 6.0.1 - sha256: 2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615 - requires_dist: - - colorama ; extra == 'colors' - - setuptools ; extra == 'plugins' - requires_python: '>=3.9.0' -- pypi: https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl - name: itsdangerous - version: 2.2.0 - sha256: c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl - name: jedi - version: 0.19.2 - sha256: a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9 - requires_dist: - - parso>=0.8.4,<0.9.0 - - jinja2==2.11.3 ; extra == 'docs' - - markupsafe==1.1.1 ; extra == 'docs' - - pygments==2.8.1 ; extra == 'docs' - - alabaster==0.7.12 ; extra == 'docs' - - babel==2.9.1 ; extra == 'docs' - - chardet==4.0.0 ; extra == 'docs' - - commonmark==0.8.1 ; extra == 'docs' - - docutils==0.17.1 ; extra == 'docs' - - future==0.18.2 ; extra == 'docs' - - idna==2.10 ; extra == 'docs' - - imagesize==1.2.0 ; extra == 'docs' - - mock==1.0.1 ; extra == 'docs' - - packaging==20.9 ; extra == 'docs' - - pyparsing==2.4.7 ; extra == 'docs' - - pytz==2021.1 ; extra == 'docs' - - readthedocs-sphinx-ext==2.1.4 ; extra == 'docs' - - recommonmark==0.5.0 ; extra == 'docs' - - requests==2.25.1 ; extra == 'docs' - - six==1.15.0 ; extra == 'docs' - - snowballstemmer==2.1.0 ; extra == 'docs' - - sphinx-rtd-theme==0.4.3 ; extra == 'docs' - - sphinx==1.8.5 ; extra == 'docs' - - sphinxcontrib-serializinghtml==1.1.4 ; extra == 'docs' - - sphinxcontrib-websupport==1.2.4 ; extra == 'docs' - - urllib3==1.26.4 ; extra == 'docs' - - flake8==5.0.4 ; extra == 'qa' - - mypy==0.971 ; extra == 'qa' - - types-setuptools==67.2.0.1 ; extra == 'qa' - - django ; extra == 'testing' - - attrs ; extra == 'testing' - - colorama ; extra == 'testing' - - docopt ; extra == 'testing' - - pytest<9.0.0 ; extra == 'testing' - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - name: jinja2 - version: 3.1.6 - sha256: 85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 - requires_dist: - - markupsafe>=2.0 - - babel>=2.7 ; extra == 'i18n' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/41/9f/3500910d5a98549e3098807493851eeef2b89cdd3032227558a104dfe926/json5-0.12.0-py3-none-any.whl - name: json5 - version: 0.12.0 - sha256: 6d37aa6c08b0609f16e1ec5ff94697e2cbbfbad5ac112afa05794da9ab7810db - requires_dist: - - build==1.2.2.post1 ; extra == 'dev' - - coverage==7.5.4 ; python_full_version < '3.9' and extra == 'dev' - - coverage==7.8.0 ; python_full_version >= '3.9' and extra == 'dev' - - mypy==1.14.1 ; python_full_version < '3.9' and extra == 'dev' - - mypy==1.15.0 ; python_full_version >= '3.9' and extra == 'dev' - - pip==25.0.1 ; extra == 'dev' - - pylint==3.2.7 ; python_full_version < '3.9' and extra == 'dev' - - pylint==3.3.6 ; python_full_version >= '3.9' and extra == 'dev' - - ruff==0.11.2 ; extra == 'dev' - - twine==6.1.0 ; extra == 'dev' - - uv==0.6.11 ; extra == 'dev' - requires_python: '>=3.8.0' -- pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl - name: jsonpointer - version: 3.0.0 - sha256: 13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/fe/54/c86cd8e011fe98803d7e382fd67c0df5ceab8d2b7ad8c5a81524f791551c/jsonschema-4.25.0-py3-none-any.whl - name: jsonschema - version: 4.25.0 - sha256: 24c2e8da302de79c8b9382fee3e76b355e44d2a4364bb207159ce10b517bd716 - requires_dist: - - attrs>=22.2.0 - - jsonschema-specifications>=2023.3.6 - - referencing>=0.28.4 - - rpds-py>=0.7.1 - - fqdn ; extra == 'format' - - idna ; extra == 'format' - - isoduration ; extra == 'format' - - jsonpointer>1.13 ; extra == 'format' - - rfc3339-validator ; extra == 'format' - - rfc3987 ; extra == 'format' - - uri-template ; extra == 'format' - - webcolors>=1.11 ; extra == 'format' - - fqdn ; extra == 'format-nongpl' - - idna ; extra == 'format-nongpl' - - isoduration ; extra == 'format-nongpl' - - jsonpointer>1.13 ; extra == 'format-nongpl' - - rfc3339-validator ; extra == 'format-nongpl' - - rfc3986-validator>0.1.0 ; extra == 'format-nongpl' - - rfc3987-syntax>=1.1.0 ; extra == 'format-nongpl' - - uri-template ; extra == 'format-nongpl' - - webcolors>=24.6.0 ; extra == 'format-nongpl' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl - name: jsonschema-specifications - version: 2025.4.1 - sha256: 4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af - requires_dist: - - referencing>=0.31.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/38/64/285f20a31679bf547b75602702f7800e74dbabae36ef324f716c02804753/jupyter-1.1.1-py2.py3-none-any.whl - name: jupyter - version: 1.1.1 - sha256: 7a59533c22af65439b24bbe60373a4e95af8f16ac65a6c00820ad378e3f7cc83 - requires_dist: - - notebook - - jupyter-console - - nbconvert - - ipykernel - - ipywidgets - - jupyterlab -- pypi: https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl - name: jupyter-client - version: 8.6.3 - sha256: e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f - requires_dist: - - importlib-metadata>=4.8.3 ; python_full_version < '3.10' - - jupyter-core>=4.12,!=5.0.* - - python-dateutil>=2.8.2 - - pyzmq>=23.0 - - tornado>=6.2 - - traitlets>=5.3 - - ipykernel ; extra == 'docs' - - myst-parser ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - sphinx>=4 ; extra == 'docs' - - sphinxcontrib-github-alt ; extra == 'docs' - - sphinxcontrib-spelling ; extra == 'docs' - - coverage ; extra == 'test' - - ipykernel>=6.14 ; extra == 'test' - - mypy ; extra == 'test' - - paramiko ; sys_platform == 'win32' and extra == 'test' - - pre-commit ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-jupyter[client]>=0.4.1 ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest<8.2.0 ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/ca/77/71d78d58f15c22db16328a476426f7ac4a60d3a5a7ba3b9627ee2f7903d4/jupyter_console-6.6.3-py3-none-any.whl - name: jupyter-console - version: 6.6.3 - sha256: 309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485 - requires_dist: - - ipykernel>=6.14 - - ipython - - jupyter-client>=7.0.0 - - jupyter-core>=4.12,!=5.0.* - - prompt-toolkit>=3.0.30 - - pygments - - pyzmq>=17 - - traitlets>=5.4 - - flaky ; extra == 'test' - - pexpect ; extra == 'test' - - pytest ; extra == 'test' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/2f/57/6bffd4b20b88da3800c5d691e0337761576ee688eb01299eae865689d2df/jupyter_core-5.8.1-py3-none-any.whl - name: jupyter-core - version: 5.8.1 - sha256: c28d268fc90fb53f1338ded2eb410704c5449a358406e8a948b75706e24863d0 - requires_dist: - - platformdirs>=2.5 - - pywin32>=300 ; platform_python_implementation != 'PyPy' and sys_platform == 'win32' - - traitlets>=5.3 - - intersphinx-registry ; extra == 'docs' - - myst-parser ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - sphinxcontrib-spelling ; extra == 'docs' - - traitlets ; extra == 'docs' - - ipykernel ; extra == 'test' - - pre-commit ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest<9 ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl - name: jupyter-events - version: 0.12.0 - sha256: 6464b2fa5ad10451c3d35fabc75eab39556ae1e2853ad0c0cc31b656731a97fb - requires_dist: - - jsonschema[format-nongpl]>=4.18.0 - - packaging - - python-json-logger>=2.0.4 - - pyyaml>=5.3 - - referencing - - rfc3339-validator - - rfc3986-validator>=0.1.1 - - traitlets>=5.3 - - click ; extra == 'cli' - - rich ; extra == 'cli' - - jupyterlite-sphinx ; extra == 'docs' - - myst-parser ; extra == 'docs' - - pydata-sphinx-theme>=0.16 ; extra == 'docs' - - sphinx>=8 ; extra == 'docs' - - sphinxcontrib-spelling ; extra == 'docs' - - click ; extra == 'test' - - pre-commit ; extra == 'test' - - pytest-asyncio>=0.19.0 ; extra == 'test' - - pytest-console-scripts ; extra == 'test' - - pytest>=7.0 ; extra == 'test' - - rich ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/47/7c/12f68daf85b469b4896d5e4a629baa33c806d61de75ac5b39d8ef27ec4a2/jupyter_lsp-2.2.6-py3-none-any.whl - name: jupyter-lsp - version: 2.2.6 - sha256: 283783752bf0b459ee7fa88effa72104d87dd343b82d5c06cf113ef755b15b6d - requires_dist: - - jupyter-server>=1.1.2 - - importlib-metadata>=4.8.3 ; python_full_version < '3.10' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/46/1f/5ebbced977171d09a7b0c08a285ff9a20aafb9c51bde07e52349ff1ddd71/jupyter_server-2.16.0-py3-none-any.whl - name: jupyter-server - version: 2.16.0 - sha256: 3d8db5be3bc64403b1c65b400a1d7f4647a5ce743f3b20dbdefe8ddb7b55af9e - requires_dist: - - anyio>=3.1.0 - - argon2-cffi>=21.1 - - jinja2>=3.0.3 - - jupyter-client>=7.4.4 - - jupyter-core>=4.12,!=5.0.* - - jupyter-events>=0.11.0 - - jupyter-server-terminals>=0.4.4 - - nbconvert>=6.4.4 - - nbformat>=5.3.0 - - overrides>=5.0 - - packaging>=22.0 - - prometheus-client>=0.9 - - pywinpty>=2.0.1 ; os_name == 'nt' - - pyzmq>=24 - - send2trash>=1.8.2 - - terminado>=0.8.3 - - tornado>=6.2.0 - - traitlets>=5.6.0 - - websocket-client>=1.7 - - ipykernel ; extra == 'docs' - - jinja2 ; extra == 'docs' - - jupyter-client ; extra == 'docs' - - myst-parser ; extra == 'docs' - - nbformat ; extra == 'docs' - - prometheus-client ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - send2trash ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - sphinxcontrib-github-alt ; extra == 'docs' - - sphinxcontrib-openapi>=0.8.0 ; extra == 'docs' - - sphinxcontrib-spelling ; extra == 'docs' - - sphinxemoji ; extra == 'docs' - - tornado ; extra == 'docs' - - typing-extensions ; extra == 'docs' - - flaky ; extra == 'test' - - ipykernel ; extra == 'test' - - pre-commit ; extra == 'test' - - pytest-console-scripts ; extra == 'test' - - pytest-jupyter[server]>=0.7 ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest>=7.0,<9 ; extra == 'test' - - requests ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl - name: jupyter-server-terminals - version: 0.5.3 - sha256: 41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa - requires_dist: - - pywinpty>=2.0.3 ; os_name == 'nt' - - terminado>=0.8.3 - - jinja2 ; extra == 'docs' - - jupyter-server ; extra == 'docs' - - mistune<4.0 ; extra == 'docs' - - myst-parser ; extra == 'docs' - - nbformat ; extra == 'docs' - - packaging ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - sphinxcontrib-github-alt ; extra == 'docs' - - sphinxcontrib-openapi ; extra == 'docs' - - sphinxcontrib-spelling ; extra == 'docs' - - sphinxemoji ; extra == 'docs' - - tornado ; extra == 'docs' - - jupyter-server>=2.0.0 ; extra == 'test' - - pytest-jupyter[server]>=0.5.3 ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest>=7.0 ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/47/74/e144ce85b34414e44b14c1f6bf2e3bfe17964c8e5670ebdc7629f2e53672/jupyterlab-4.4.5-py3-none-any.whl - name: jupyterlab - version: 4.4.5 - sha256: e76244cceb2d1fb4a99341f3edc866f2a13a9e14c50368d730d75d8017be0863 - requires_dist: - - async-lru>=1.0.0 - - httpx>=0.25.0 - - importlib-metadata>=4.8.3 ; python_full_version < '3.10' - - ipykernel>=6.5.0 - - jinja2>=3.0.3 - - jupyter-core - - jupyter-lsp>=2.0.0 - - jupyter-server>=2.4.0,<3 - - jupyterlab-server>=2.27.1,<3 - - notebook-shim>=0.2 - - packaging - - setuptools>=41.1.0 - - tomli>=1.2.2 ; python_full_version < '3.11' - - tornado>=6.2.0 - - traitlets - - build ; extra == 'dev' - - bump2version ; extra == 'dev' - - coverage ; extra == 'dev' - - hatch ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - ruff==0.11.4 ; extra == 'dev' - - jsx-lexer ; extra == 'docs' - - myst-parser ; extra == 'docs' - - pydata-sphinx-theme>=0.13.0 ; extra == 'docs' - - pytest ; extra == 'docs' - - pytest-check-links ; extra == 'docs' - - pytest-jupyter ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx>=1.8,<8.2.0 ; extra == 'docs' - - altair==5.5.0 ; extra == 'docs-screenshots' - - ipython==8.16.1 ; extra == 'docs-screenshots' - - ipywidgets==8.1.5 ; extra == 'docs-screenshots' - - jupyterlab-geojson==3.4.0 ; extra == 'docs-screenshots' - - jupyterlab-language-pack-zh-cn==4.3.post1 ; extra == 'docs-screenshots' - - matplotlib==3.10.0 ; extra == 'docs-screenshots' - - nbconvert>=7.0.0 ; extra == 'docs-screenshots' - - pandas==2.2.3 ; extra == 'docs-screenshots' - - scipy==1.15.1 ; extra == 'docs-screenshots' - - vega-datasets==0.9.0 ; extra == 'docs-screenshots' - - coverage ; extra == 'test' - - pytest-check-links>=0.7 ; extra == 'test' - - pytest-console-scripts ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-jupyter>=0.5.3 ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest-tornasync ; extra == 'test' - - pytest>=7.0 ; extra == 'test' - - requests ; extra == 'test' - - requests-cache ; extra == 'test' - - virtualenv ; extra == 'test' - - copier>=9,<10 ; extra == 'upgrade-extension' - - jinja2-time<0.3 ; extra == 'upgrade-extension' - - pydantic<3.0 ; extra == 'upgrade-extension' - - pyyaml-include<3.0 ; extra == 'upgrade-extension' - - tomli-w<2.0 ; extra == 'upgrade-extension' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl - name: jupyterlab-pygments - version: 0.3.0 - sha256: 841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl - name: jupyterlab-server - version: 2.27.3 - sha256: e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4 - requires_dist: - - babel>=2.10 - - importlib-metadata>=4.8.3 ; python_full_version < '3.10' - - jinja2>=3.0.3 - - json5>=0.9.0 - - jsonschema>=4.18.0 - - jupyter-server>=1.21,<3 - - packaging>=21.3 - - requests>=2.31 - - autodoc-traits ; extra == 'docs' - - jinja2<3.2.0 ; extra == 'docs' - - mistune<4 ; extra == 'docs' - - myst-parser ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - sphinx ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinxcontrib-openapi>0.8 ; extra == 'docs' - - openapi-core~=0.18.0 ; extra == 'openapi' - - ruamel-yaml ; extra == 'openapi' - - hatch ; extra == 'test' - - ipykernel ; extra == 'test' - - openapi-core~=0.18.0 ; extra == 'test' - - openapi-spec-validator>=0.6.0,<0.8.0 ; extra == 'test' - - pytest-console-scripts ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-jupyter[server]>=0.6.2 ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest>=7.0,<8 ; extra == 'test' - - requests-mock ; extra == 'test' - - ruamel-yaml ; extra == 'test' - - sphinxcontrib-spelling ; extra == 'test' - - strict-rfc3339 ; extra == 'test' - - werkzeug ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/43/6a/ca128561b22b60bd5a0c4ea26649e68c8556b82bc70a0c396eebc977fe86/jupyterlab_widgets-3.0.15-py3-none-any.whl - name: jupyterlab-widgets - version: 3.0.15 - sha256: d59023d7d7ef71400d51e6fee9a88867f6e65e10a4201605d2d7f3e8f012a31c - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/2d/00/d90b10b962b4277f5e64a78b6609968859ff86889f5b898c1a778c06ec00/lark-1.2.2-py3-none-any.whl - name: lark - version: 1.2.2 - sha256: c2276486b02f0f1b90be155f2c8ba4a8e194d42775786db622faccd652d8e80c - requires_dist: - - atomicwrites ; extra == 'atomic-cache' - - interegular>=0.3.1,<0.4.0 ; extra == 'interegular' - - js2py ; extra == 'nearley' - - regex ; extra == 'regex' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/e7/1e/fb441c07b6662ec1fc92b249225ba6e6e5221b05623cb0131d082f782edc/lazy_object_proxy-1.11.0-py3-none-any.whl - name: lazy-object-proxy - version: 1.11.0 - sha256: a56a5093d433341ff7da0e89f9b486031ccd222ec8e52ec84d0ec1cdc819674b - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1423503_1.conda - sha256: 1a620f27d79217c1295049ba214c2f80372062fd251b569e9873d4a953d27554 - md5: 0be7c6e070c19105f966d3758448d018 - depends: - - __glibc >=2.17,<3.0.a0 - constrains: - - binutils_impl_linux-64 2.44 - license: GPL-3.0-only - license_family: GPL - purls: [] - size: 676044 - timestamp: 1752032747103 -- pypi: https://files.pythonhosted.org/packages/7d/7d/eb341bdc11f1147e7edeccffd0f2f785eff014e72134f5e46067472012b0/libcst-1.8.2-cp312-cp312-manylinux_2_28_x86_64.whl - name: libcst - version: 1.8.2 - sha256: 460fcf3562f078781e1504983cb11909eb27a1d46eaa99e65c4b0fafdc298298 - requires_dist: - - pyyaml>=5.2 ; python_full_version < '3.13' - - pyyaml-ft>=8.0.0 ; python_full_version >= '3.13' - - typing-extensions ; python_full_version < '3.10' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda - sha256: da2080da8f0288b95dd86765c801c6e166c4619b910b11f9a8446fb852438dc2 - md5: 4211416ecba1866fab0c6470986c22d6 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - constrains: - - expat 2.7.1.* - license: MIT - license_family: MIT - purls: [] - size: 74811 - timestamp: 1752719572741 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - sha256: 764432d32db45466e87f10621db5b74363a9f847d2b8b1f9743746cd160f06ab - md5: ede4673863426c0883c0063d853bbd85 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: MIT - license_family: MIT - purls: [] - size: 57433 - timestamp: 1743434498161 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_3.conda - sha256: 59a87161212abe8acc57d318b0cc8636eb834cdfdfddcf1f588b5493644b39a3 - md5: 9e60c55e725c20d23125a5f0dd69af5d - depends: - - __glibc >=2.17,<3.0.a0 - - _openmp_mutex >=4.5 - constrains: - - libgcc-ng ==15.1.0=*_3 - - libgomp 15.1.0 h767d61c_3 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 824921 - timestamp: 1750808216066 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_3.conda - sha256: b0b0a5ee6ce645a09578fc1cb70c180723346f8a45fdb6d23b3520591c6d6996 - md5: e66f2b8ad787e7beb0f846e4bd7e8493 - depends: - - libgcc 15.1.0 h767d61c_3 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 29033 - timestamp: 1750808224854 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_3.conda - sha256: 43710ab4de0cd7ff8467abff8d11e7bb0e36569df04ce1c099d48601818f11d1 - md5: 3cd1a7238a0dd3d0860fdefc496cc854 - depends: - - __glibc >=2.17,<3.0.a0 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 447068 - timestamp: 1750808138400 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 - md5: 1a580f7796c7bf6393fddb8bbbde58dc - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - constrains: - - xz 5.8.1.* - license: 0BSD - purls: [] - size: 112894 - timestamp: 1749230047870 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - sha256: 927fe72b054277cde6cb82597d0fcf6baf127dcbce2e0a9d8925a68f1265eef5 - md5: d864d34357c3b65a4b731f78c0801dc4 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: LGPL-2.1-only - license_family: GPL - purls: [] - size: 33731 - timestamp: 1750274110928 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.3-hee844dc_1.conda - sha256: 8c4faf560815a6d6b5edadc019f76d22a45171eaa707a1f1d1898ceda74b2e3f - md5: 18d2ac95b507ada9ca159a6bd73255f7 - depends: - - __glibc >=2.17,<3.0.a0 - - icu >=75.1,<76.0a0 - - libgcc >=14 - - libzlib >=1.3.1,<2.0a0 - license: blessing - purls: [] - size: 936339 - timestamp: 1753262589168 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_3.conda - sha256: 7650837344b7850b62fdba02155da0b159cf472b9ab59eb7b472f7bd01dff241 - md5: 6d11a5edae89fe413c0569f16d308f5a - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc 15.1.0 h767d61c_3 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 3896407 - timestamp: 1750808251302 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_3.conda - sha256: bbaea1ecf973a7836f92b8ebecc94d3c758414f4de39d2cc6818a3d10cb3216b - md5: 57541755b5a51691955012b8e197c06c - depends: - - libstdcxx 15.1.0 h8f9b012_3 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 29093 - timestamp: 1750808292700 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - sha256: 787eb542f055a2b3de553614b25f09eefb0a0931b0c87dbcce6efdfd92f04f18 - md5: 40b61aab5c7ba9ff276c41cfffe6b80b - depends: - - libgcc-ng >=12 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 33601 - timestamp: 1680112270483 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c - md5: 5aa797f8787fe7a17d1b0821485b5adc - depends: - - libgcc-ng >=12 - license: LGPL-2.1-or-later - purls: [] - size: 100393 - timestamp: 1702724383534 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 - md5: edb0dca6bc32e4f4789199455a1dbeb8 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - constrains: - - zlib 1.3.1 *_2 - license: Zlib - license_family: Other - purls: [] - size: 60963 - timestamp: 1727963148474 -- pypi: https://files.pythonhosted.org/packages/04/1e/b832de447dee8b582cac175871d2f6c3d5077cc56d5575cadba1fd1cccfa/linkify_it_py-2.0.3-py3-none-any.whl - name: linkify-it-py - version: 2.0.3 - sha256: 6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79 - requires_dist: - - uc-micro-py - - pytest ; extra == 'benchmark' - - pytest-benchmark ; extra == 'benchmark' - - pre-commit ; extra == 'dev' - - isort ; extra == 'dev' - - flake8 ; extra == 'dev' - - black ; extra == 'dev' - - pyproject-flake8 ; extra == 'dev' - - sphinx ; extra == 'doc' - - sphinx-book-theme ; extra == 'doc' - - myst-parser ; extra == 'doc' - - pytest ; extra == 'test' - - coverage ; extra == 'test' - - pytest-cov ; extra == 'test' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/c8/22/9460e311f340cb62d26a38c419b1381b8593b0bb6b5d1f056938b086d362/lockfile-0.12.2-py2.py3-none-any.whl - name: lockfile - version: 0.12.2 - sha256: 6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa -- pypi: https://files.pythonhosted.org/packages/87/fb/99f81ac72ae23375f22b7afdb7642aba97c00a713c217124420147681a2f/mako-1.3.10-py3-none-any.whl - name: mako - version: 1.3.10 - sha256: baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59 - requires_dist: - - markupsafe>=0.9.2 - - pytest ; extra == 'testing' - - babel ; extra == 'babel' - - lingua ; extra == 'lingua' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl - name: markdown-it-py - version: 3.0.0 - sha256: 355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 - requires_dist: - - mdurl~=0.1 - - psutil ; extra == 'benchmarking' - - pytest ; extra == 'benchmarking' - - pytest-benchmark ; extra == 'benchmarking' - - pre-commit~=3.0 ; extra == 'code-style' - - commonmark~=0.9 ; extra == 'compare' - - markdown~=3.4 ; extra == 'compare' - - mistletoe~=1.0 ; extra == 'compare' - - mistune~=2.0 ; extra == 'compare' - - panflute~=2.3 ; extra == 'compare' - - linkify-it-py>=1,<3 ; extra == 'linkify' - - mdit-py-plugins ; extra == 'plugins' - - gprof2dot ; extra == 'profiling' - - mdit-py-plugins ; extra == 'rtd' - - myst-parser ; extra == 'rtd' - - pyyaml ; extra == 'rtd' - - sphinx ; extra == 'rtd' - - sphinx-copybutton ; extra == 'rtd' - - sphinx-design ; extra == 'rtd' - - sphinx-book-theme ; extra == 'rtd' - - jupyter-sphinx ; extra == 'rtd' - - coverage ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: markupsafe - version: 3.0.2 - sha256: e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl - name: matplotlib-inline - version: 0.1.7 - sha256: df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca - requires_dist: - - traitlets - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - name: mdurl - version: 0.1.2 - sha256: 84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/b6/4b/6497ffb463b1b75e04b348ef31070606d43e3c503fa295383538ded999c9/methodtools-0.4.7-py2.py3-none-any.whl - name: methodtools - version: 0.4.7 - sha256: 5e188c780b236adc12e75b5f078c5afb419ef99eb648569fc6d7071f053a1f11 - requires_dist: - - wirerope>=0.4.7 - - sphinx ; extra == 'doc' - - pytest>=4.6.7 ; extra == 'test' - - pytest-cov>=2.6.1 ; extra == 'test' - - functools32>=3.2.3.post2 ; python_full_version < '3' and extra == 'test' -- pypi: https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl - name: mistune - version: 3.1.3 - sha256: 1a32314113cff28aa6432e99e522677c8587fd83e3d51c29b82a52409c842bd9 - requires_dist: - - typing-extensions ; python_full_version < '3.11' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/2b/9f/7ba6f94fc1e9ac3d2b853fdff3035fb2fa5afbed898c4a72b8a020610594/more_itertools-10.7.0-py3-none-any.whl - name: more-itertools - version: 10.7.0 - sha256: d43980384673cb07d2f7d2d918c616b30c659c089ee23953f601d6609c67510e - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d0/ef/c5422ce8af73928d194a6606f8ae36e93a52fd5e8df5abd366903a5ca8da/msgspec-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: msgspec - version: 0.19.0 - sha256: d911c442571605e17658ca2b416fd8579c5050ac9adc5e00c2cb3126c97f73bc - requires_dist: - - pyyaml ; extra == 'yaml' - - tomli ; python_full_version < '3.11' and extra == 'toml' - - tomli-w ; extra == 'toml' - - sphinx ; extra == 'doc' - - furo ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - sphinx-design ; extra == 'doc' - - ipython ; extra == 'doc' - - pytest ; extra == 'test' - - msgpack ; extra == 'test' - - attrs ; extra == 'test' - - eval-type-backport ; python_full_version < '3.10' and extra == 'test' - - pyyaml ; extra == 'test' - - tomli ; python_full_version < '3.11' and extra == 'test' - - tomli-w ; extra == 'test' - - pre-commit ; extra == 'dev' - - coverage ; extra == 'dev' - - mypy ; extra == 'dev' - - pyright ; extra == 'dev' - - sphinx ; extra == 'dev' - - furo ; extra == 'dev' - - sphinx-copybutton ; extra == 'dev' - - sphinx-design ; extra == 'dev' - - ipython ; extra == 'dev' - - pytest ; extra == 'dev' - - msgpack ; extra == 'dev' - - attrs ; extra == 'dev' - - eval-type-backport ; python_full_version < '3.10' and extra == 'dev' - - pyyaml ; extra == 'dev' - - tomli ; python_full_version < '3.11' and extra == 'dev' - - tomli-w ; extra == 'dev' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0b/64/d6120eca3835baf7179e6797a0b61d6c47e0bc2324b1f6819d8428d5b9ba/mypy-1.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: mypy - version: 1.17.0 - sha256: 1051df7ec0886fa246a530ae917c473491e9a0ba6938cfd0ec2abc1076495c3e - requires_dist: - - typing-extensions>=4.6.0 - - mypy-extensions>=1.0.0 - - pathspec>=0.9.0 - - tomli>=1.1.0 ; python_full_version < '3.11' - - psutil>=4.0 ; extra == 'dmypy' - - setuptools>=50 ; extra == 'mypyc' - - lxml ; extra == 'reports' - - pip ; extra == 'install-types' - - orjson ; extra == 'faster-cache' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - name: mypy-extensions - version: 1.1.0 - sha256: 1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl - name: nbclient - version: 0.10.2 - sha256: 4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d - requires_dist: - - jupyter-client>=6.1.12 - - jupyter-core>=4.12,!=5.0.* - - nbformat>=5.1 - - traitlets>=5.4 - - pre-commit ; extra == 'dev' - - autodoc-traits ; extra == 'docs' - - flaky ; extra == 'docs' - - ipykernel>=6.19.3 ; extra == 'docs' - - ipython ; extra == 'docs' - - ipywidgets ; extra == 'docs' - - mock ; extra == 'docs' - - moto ; extra == 'docs' - - myst-parser ; extra == 'docs' - - nbconvert>=7.1.0 ; extra == 'docs' - - pytest-asyncio ; extra == 'docs' - - pytest-cov>=4.0 ; extra == 'docs' - - pytest>=7.0,<8 ; extra == 'docs' - - sphinx-book-theme ; extra == 'docs' - - sphinx>=1.7 ; extra == 'docs' - - sphinxcontrib-spelling ; extra == 'docs' - - testpath ; extra == 'docs' - - xmltodict ; extra == 'docs' - - flaky ; extra == 'test' - - ipykernel>=6.19.3 ; extra == 'test' - - ipython ; extra == 'test' - - ipywidgets ; extra == 'test' - - nbconvert>=7.1.0 ; extra == 'test' - - pytest-asyncio ; extra == 'test' - - pytest-cov>=4.0 ; extra == 'test' - - pytest>=7.0,<8 ; extra == 'test' - - testpath ; extra == 'test' - - xmltodict ; extra == 'test' - requires_python: '>=3.9.0' -- pypi: https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl - name: nbconvert - version: 7.16.6 - sha256: 1375a7b67e0c2883678c48e506dc320febb57685e5ee67faa51b18a90f3a712b - requires_dist: - - beautifulsoup4 - - bleach[css]!=5.0.0 - - defusedxml - - importlib-metadata>=3.6 ; python_full_version < '3.10' - - jinja2>=3.0 - - jupyter-core>=4.7 - - jupyterlab-pygments - - markupsafe>=2.0 - - mistune>=2.0.3,<4 - - nbclient>=0.5.0 - - nbformat>=5.7 - - packaging - - pandocfilters>=1.4.1 - - pygments>=2.4.1 - - traitlets>=5.1 - - flaky ; extra == 'all' - - ipykernel ; extra == 'all' - - ipython ; extra == 'all' - - ipywidgets>=7.5 ; extra == 'all' - - myst-parser ; extra == 'all' - - nbsphinx>=0.2.12 ; extra == 'all' - - playwright ; extra == 'all' - - pydata-sphinx-theme ; extra == 'all' - - pyqtwebengine>=5.15 ; extra == 'all' - - pytest>=7 ; extra == 'all' - - sphinx==5.0.2 ; extra == 'all' - - sphinxcontrib-spelling ; extra == 'all' - - tornado>=6.1 ; extra == 'all' - - ipykernel ; extra == 'docs' - - ipython ; extra == 'docs' - - myst-parser ; extra == 'docs' - - nbsphinx>=0.2.12 ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - sphinx==5.0.2 ; extra == 'docs' - - sphinxcontrib-spelling ; extra == 'docs' - - pyqtwebengine>=5.15 ; extra == 'qtpdf' - - pyqtwebengine>=5.15 ; extra == 'qtpng' - - tornado>=6.1 ; extra == 'serve' - - flaky ; extra == 'test' - - ipykernel ; extra == 'test' - - ipywidgets>=7.5 ; extra == 'test' - - pytest>=7 ; extra == 'test' - - playwright ; extra == 'webpdf' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl - name: nbformat - version: 5.10.4 - sha256: 3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b - requires_dist: - - fastjsonschema>=2.15 - - jsonschema>=2.6 - - jupyter-core>=4.12,!=5.0.* - - traitlets>=5.1 - - myst-parser ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - sphinx ; extra == 'docs' - - sphinxcontrib-github-alt ; extra == 'docs' - - sphinxcontrib-spelling ; extra == 'docs' - - pep440 ; extra == 'test' - - pre-commit ; extra == 'test' - - pytest ; extra == 'test' - - testpath ; extra == 'test' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 - md5: 47e340acb35de30501a76c7c799c41d7 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: X11 AND BSD-3-Clause - purls: [] - size: 891641 - timestamp: 1738195959188 -- pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl - name: nest-asyncio - version: 1.6.0 - sha256: 87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c - requires_python: '>=3.5' -- pypi: https://files.pythonhosted.org/packages/b3/c0/e64d2047fd752249b0b69f6aee2a7049eb94e7273e5baabc8b8ad05cc068/notebook-7.4.4-py3-none-any.whl - name: notebook - version: 7.4.4 - sha256: 32840f7f777b6bff79bb101159336e9b332bdbfba1495b8739e34d1d65cbc1c0 - requires_dist: - - jupyter-server>=2.4.0,<3 - - jupyterlab-server>=2.27.1,<3 - - jupyterlab>=4.4.4,<4.5 - - notebook-shim>=0.2,<0.3 - - tornado>=6.2.0 - - hatch ; extra == 'dev' - - pre-commit ; extra == 'dev' - - myst-parser ; extra == 'docs' - - nbsphinx ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - sphinx>=1.3.6 ; extra == 'docs' - - sphinxcontrib-github-alt ; extra == 'docs' - - sphinxcontrib-spelling ; extra == 'docs' - - importlib-resources>=5.0 ; python_full_version < '3.10' and extra == 'test' - - ipykernel ; extra == 'test' - - jupyter-server[test]>=2.4.0,<3 ; extra == 'test' - - jupyterlab-server[test]>=2.27.1,<3 ; extra == 'test' - - nbval ; extra == 'test' - - pytest-console-scripts ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest-tornasync ; extra == 'test' - - pytest>=7.0 ; extra == 'test' - - requests ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl - name: notebook-shim - version: 0.2.4 - sha256: 411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef - requires_dist: - - jupyter-server>=1.8,<3 - - pytest ; extra == 'test' - - pytest-console-scripts ; extra == 'test' - - pytest-jupyter ; extra == 'test' - - pytest-tornasync ; extra == 'test' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/1b/f5/515f98d659ab0cbe3738da153eddae22186fd38f05a808511e10f04cf679/numcodecs-0.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: numcodecs - version: 0.16.1 - sha256: 82cc70592ec18060786b1bfa0da23afd2a7807d7975d766e626954d6628ec609 - requires_dist: - - numpy>=1.24 - - typing-extensions - - sphinx ; extra == 'docs' - - sphinx-issues ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - numpydoc ; extra == 'docs' - - coverage ; extra == 'test' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - importlib-metadata ; extra == 'test-extras' - - msgpack ; extra == 'msgpack' - - zfpy>=1.0.0 ; extra == 'zfpy' - - pcodec>=0.3,<0.4 ; extra == 'pcodec' - - crc32c>=2.7 ; extra == 'crc32c' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/6e/45/c51cb248e679a6c6ab14b7a8e3ead3f4a3fe7425fc7a6f98b3f147bec532/numpy-2.3.1-cp312-cp312-manylinux_2_28_x86_64.whl - name: numpy - version: 2.3.1 - sha256: e7cbf5a5eafd8d230a3ce356d892512185230e4781a361229bd902ff403bc660 - requires_python: '>=3.11' -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.1-h7b32b05_0.conda - sha256: 942347492164190559e995930adcdf84e2fea05307ec8012c02a505f5be87462 - md5: c87df2ab1448ba69169652ab9547082d - depends: - - __glibc >=2.17,<3.0.a0 - - ca-certificates - - libgcc >=13 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 3131002 - timestamp: 1751390382076 -- pypi: https://files.pythonhosted.org/packages/1d/5a/3f8d078dbf55d18442f6a2ecedf6786d81d7245844b2b20ce2b8ad6f0307/opentelemetry_api-1.35.0-py3-none-any.whl - name: opentelemetry-api - version: 1.35.0 - sha256: c4ea7e258a244858daf18474625e9cc0149b8ee354f37843415771a40c25ee06 - requires_dist: - - importlib-metadata>=6.0,<8.8.0 - - typing-extensions>=4.5.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/cf/db/2da28358d3101ca936c1643becbb4ebd69e9e48acf27f153d735a4813c6b/opentelemetry_exporter_otlp-1.35.0-py3-none-any.whl - name: opentelemetry-exporter-otlp - version: 1.35.0 - sha256: 8e6bb9025f6238db7d69bba7ee37c77e4858d0a1ff22a9e126f7c9e017e83afe - requires_dist: - - opentelemetry-exporter-otlp-proto-grpc==1.35.0 - - opentelemetry-exporter-otlp-proto-http==1.35.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/5a/2c/e31dd3c719bff87fa77391eb7f38b1430d22868c52312cba8aad60f280e5/opentelemetry_exporter_otlp_proto_common-1.35.0-py3-none-any.whl - name: opentelemetry-exporter-otlp-proto-common - version: 1.35.0 - sha256: 863465de697ae81279ede660f3918680b4480ef5f69dcdac04f30722ed7b74cc - requires_dist: - - opentelemetry-proto==1.35.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f4/a6/3f60a77279e6a3dc21fc076dcb51be159a633b0bba5cba9fb804062a9332/opentelemetry_exporter_otlp_proto_grpc-1.35.0-py3-none-any.whl - name: opentelemetry-exporter-otlp-proto-grpc - version: 1.35.0 - sha256: ee31203eb3e50c7967b8fa71db366cc355099aca4e3726e489b248cdb2fd5a62 - requires_dist: - - googleapis-common-protos~=1.57 - - grpcio>=1.63.2,<2.0.0 ; python_full_version < '3.13' - - grpcio>=1.66.2,<2.0.0 ; python_full_version >= '3.13' - - opentelemetry-api~=1.15 - - opentelemetry-exporter-otlp-proto-common==1.35.0 - - opentelemetry-proto==1.35.0 - - opentelemetry-sdk~=1.35.0 - - typing-extensions>=4.6.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d4/71/f118cd90dc26797077931dd598bde5e0cc652519db166593f962f8fcd022/opentelemetry_exporter_otlp_proto_http-1.35.0-py3-none-any.whl - name: opentelemetry-exporter-otlp-proto-http - version: 1.35.0 - sha256: 9a001e3df3c7f160fb31056a28ed7faa2de7df68877ae909516102ae36a54e1d - requires_dist: - - googleapis-common-protos~=1.52 - - opentelemetry-api~=1.15 - - opentelemetry-exporter-otlp-proto-common==1.35.0 - - opentelemetry-proto==1.35.0 - - opentelemetry-sdk~=1.35.0 - - requests~=2.7 - - typing-extensions>=4.5.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/00/a7/3f05de580da7e8a8b8dff041d3d07a20bf3bb62d3bcc027f8fd669a73ff4/opentelemetry_proto-1.35.0-py3-none-any.whl - name: opentelemetry-proto - version: 1.35.0 - sha256: 98fffa803164499f562718384e703be8d7dfbe680192279a0429cb150a2f8809 - requires_dist: - - protobuf>=5.0,<7.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/01/4f/8e32b757ef3b660511b638ab52d1ed9259b666bdeeceba51a082ce3aea95/opentelemetry_sdk-1.35.0-py3-none-any.whl - name: opentelemetry-sdk - version: 1.35.0 - sha256: 223d9e5f5678518f4842311bb73966e0b6db5d1e0b74e35074c052cd2487f800 - requires_dist: - - opentelemetry-api==1.35.0 - - opentelemetry-semantic-conventions==0.56b0 - - typing-extensions>=4.5.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c7/3f/e80c1b017066a9d999efffe88d1cce66116dcf5cb7f80c41040a83b6e03b/opentelemetry_semantic_conventions-0.56b0-py3-none-any.whl - name: opentelemetry-semantic-conventions - version: 0.56b0 - sha256: df44492868fd6b482511cc43a942e7194be64e94945f572db24df2e279a001a2 - requires_dist: - - opentelemetry-api==1.35.0 - - typing-extensions>=4.5.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl - name: overrides - version: 7.7.0 - sha256: c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49 - requires_dist: - - typing ; python_full_version < '3.5' - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl - name: packaging - version: '25.0' - sha256: 29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/da/01/e383018feba0a1ead6cf5fe8728e5d767fee02f06a3d800e82c489e5daaf/pandas-2.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: pandas - version: 2.3.1 - sha256: 7dcb79bf373a47d2a40cf7232928eb7540155abbc460925c2c96d2d30b006eb4 - requires_dist: - - numpy>=1.22.4 ; python_full_version < '3.11' - - numpy>=1.23.2 ; python_full_version == '3.11.*' - - numpy>=1.26.0 ; python_full_version >= '3.12' - - python-dateutil>=2.8.2 - - pytz>=2020.1 - - tzdata>=2022.7 - - hypothesis>=6.46.1 ; extra == 'test' - - pytest>=7.3.2 ; extra == 'test' - - pytest-xdist>=2.2.0 ; extra == 'test' - - pyarrow>=10.0.1 ; extra == 'pyarrow' - - bottleneck>=1.3.6 ; extra == 'performance' - - numba>=0.56.4 ; extra == 'performance' - - numexpr>=2.8.4 ; extra == 'performance' - - scipy>=1.10.0 ; extra == 'computation' - - xarray>=2022.12.0 ; extra == 'computation' - - fsspec>=2022.11.0 ; extra == 'fss' - - s3fs>=2022.11.0 ; extra == 'aws' - - gcsfs>=2022.11.0 ; extra == 'gcp' - - pandas-gbq>=0.19.0 ; extra == 'gcp' - - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.0 ; extra == 'excel' - - python-calamine>=0.1.7 ; extra == 'excel' - - pyxlsb>=1.0.10 ; extra == 'excel' - - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.0.5 ; extra == 'excel' - - pyarrow>=10.0.1 ; extra == 'parquet' - - pyarrow>=10.0.1 ; extra == 'feather' - - tables>=3.8.0 ; extra == 'hdf5' - - pyreadstat>=1.2.0 ; extra == 'spss' - - sqlalchemy>=2.0.0 ; extra == 'postgresql' - - psycopg2>=2.9.6 ; extra == 'postgresql' - - adbc-driver-postgresql>=0.8.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.0 ; extra == 'mysql' - - pymysql>=1.0.2 ; extra == 'mysql' - - sqlalchemy>=2.0.0 ; extra == 'sql-other' - - adbc-driver-postgresql>=0.8.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=0.8.0 ; extra == 'sql-other' - - beautifulsoup4>=4.11.2 ; extra == 'html' - - html5lib>=1.1 ; extra == 'html' - - lxml>=4.9.2 ; extra == 'html' - - lxml>=4.9.2 ; extra == 'xml' - - matplotlib>=3.6.3 ; extra == 'plot' - - jinja2>=3.1.2 ; extra == 'output-formatting' - - tabulate>=0.9.0 ; extra == 'output-formatting' - - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.3.0 ; extra == 'clipboard' - - zstandard>=0.19.0 ; extra == 'compression' - - dataframe-api-compat>=0.1.7 ; extra == 'consortium-standard' - - adbc-driver-postgresql>=0.8.0 ; extra == 'all' - - adbc-driver-sqlite>=0.8.0 ; extra == 'all' - - beautifulsoup4>=4.11.2 ; extra == 'all' - - bottleneck>=1.3.6 ; extra == 'all' - - dataframe-api-compat>=0.1.7 ; extra == 'all' - - fastparquet>=2022.12.0 ; extra == 'all' - - fsspec>=2022.11.0 ; extra == 'all' - - gcsfs>=2022.11.0 ; extra == 'all' - - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.46.1 ; extra == 'all' - - jinja2>=3.1.2 ; extra == 'all' - - lxml>=4.9.2 ; extra == 'all' - - matplotlib>=3.6.3 ; extra == 'all' - - numba>=0.56.4 ; extra == 'all' - - numexpr>=2.8.4 ; extra == 'all' - - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.0 ; extra == 'all' - - pandas-gbq>=0.19.0 ; extra == 'all' - - psycopg2>=2.9.6 ; extra == 'all' - - pyarrow>=10.0.1 ; extra == 'all' - - pymysql>=1.0.2 ; extra == 'all' - - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.0 ; extra == 'all' - - pytest>=7.3.2 ; extra == 'all' - - pytest-xdist>=2.2.0 ; extra == 'all' - - python-calamine>=0.1.7 ; extra == 'all' - - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.3.0 ; extra == 'all' - - scipy>=1.10.0 ; extra == 'all' - - s3fs>=2022.11.0 ; extra == 'all' - - sqlalchemy>=2.0.0 ; extra == 'all' - - tables>=3.8.0 ; extra == 'all' - - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2022.12.0 ; extra == 'all' - - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.0.5 ; extra == 'all' - - zstandard>=0.19.0 ; extra == 'all' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl - name: pandocfilters - version: 1.5.1 - sha256: 93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- pypi: https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl - name: parso - version: 0.8.4 - sha256: a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18 - requires_dist: - - flake8==5.0.4 ; extra == 'qa' - - mypy==0.971 ; extra == 'qa' - - types-setuptools==67.2.0.1 ; extra == 'qa' - - docopt ; extra == 'testing' - - pytest ; extra == 'testing' - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl - name: pathspec - version: 0.12.1 - sha256: a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/87/5d/f7a1d693e5c0f789185117d5c1d5bee104f5b0d9fbf061d715fb61c840a8/pendulum-3.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: pendulum - version: 3.1.0 - sha256: 20f74aa8029a42e327bfc150472e0e4d2358fa5d795f70460160ba81b94b6945 - requires_dist: - - python-dateutil>=2.6 - - tzdata>=2020.1 - - time-machine>=2.6.0 ; implementation_name != 'pypy' and extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - name: pexpect - version: 4.9.0 - sha256: 7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523 - requires_dist: - - ptyprocess>=0.5 -- pypi: https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl - name: platformdirs - version: 4.3.8 - sha256: ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4 - requires_dist: - - furo>=2024.8.6 ; extra == 'docs' - - proselint>=0.14 ; extra == 'docs' - - sphinx-autodoc-typehints>=3 ; extra == 'docs' - - sphinx>=8.1.3 ; extra == 'docs' - - appdirs==1.4.4 ; extra == 'test' - - covdefaults>=2.3 ; extra == 'test' - - pytest-cov>=6 ; extra == 'test' - - pytest-mock>=3.14 ; extra == 'test' - - pytest>=8.3.4 ; extra == 'test' - - mypy>=1.14.1 ; extra == 'type' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - name: pluggy - version: 1.6.0 - sha256: e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 - requires_dist: - - pre-commit ; extra == 'dev' - - tox ; extra == 'dev' - - pytest ; extra == 'testing' - - pytest-benchmark ; extra == 'testing' - - coverage ; extra == 'testing' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/32/ae/ec06af4fe3ee72d16973474f122541746196aaa16cea6f66d18b963c6177/prometheus_client-0.22.1-py3-none-any.whl - name: prometheus-client - version: 0.22.1 - sha256: cca895342e308174341b2cbf99a56bef291fbc0ef7b9e5412a0f26d653ba7094 - requires_dist: - - twisted ; extra == 'twisted' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ce/4f/5249960887b1fbe561d9ff265496d170b55a735b76724f10ef19f9e40716/prompt_toolkit-3.0.51-py3-none-any.whl - name: prompt-toolkit - version: 3.0.51 - sha256: 52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07 - requires_dist: - - wcwidth - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/fa/b1/b59d405d64d31999244643d88c45c8241c58f17cc887e73bcb90602327f8/protobuf-6.31.1-cp39-abi3-manylinux2014_x86_64.whl - name: protobuf - version: 6.31.1 - sha256: 4ee898bf66f7a8b0bd21bce523814e6fbd8c6add948045ce958b73af7e8878c6 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: psutil - version: 7.0.0 - sha256: 4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34 - requires_dist: - - pytest ; extra == 'dev' - - pytest-xdist ; extra == 'dev' - - setuptools ; extra == 'dev' - - abi3audit ; extra == 'dev' - - black==24.10.0 ; extra == 'dev' - - check-manifest ; extra == 'dev' - - coverage ; extra == 'dev' - - packaging ; extra == 'dev' - - pylint ; extra == 'dev' - - pyperf ; extra == 'dev' - - pypinfo ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - requests ; extra == 'dev' - - rstcheck ; extra == 'dev' - - ruff ; extra == 'dev' - - sphinx ; extra == 'dev' - - sphinx-rtd-theme ; extra == 'dev' - - toml-sort ; extra == 'dev' - - twine ; extra == 'dev' - - virtualenv ; extra == 'dev' - - vulture ; extra == 'dev' - - wheel ; extra == 'dev' - - pytest ; extra == 'test' - - pytest-xdist ; extra == 'test' - - setuptools ; extra == 'test' - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl - name: ptyprocess - version: 0.7.0 - sha256: 4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 -- pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl - name: pure-eval - version: 0.2.3 - sha256: 1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0 - requires_dist: - - pytest ; extra == 'tests' -- pypi: https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl - name: pycparser - version: '2.22' - sha256: c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl - name: pydantic - version: 2.11.7 - sha256: dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b - requires_dist: - - annotated-types>=0.6.0 - - pydantic-core==2.33.2 - - typing-extensions>=4.12.2 - - typing-inspection>=0.4.0 - - email-validator>=2.0.0 ; extra == 'email' - - tzdata ; python_full_version >= '3.9' and sys_platform == 'win32' and extra == 'timezone' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: pydantic-core - version: 2.33.2 - sha256: 8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1 - requires_dist: - - typing-extensions>=4.6.0,!=4.7.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - name: pygments - version: 2.19.2 - sha256: 86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b - requires_dist: - - colorama>=0.4.6 ; extra == 'windows-terminal' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl - name: pyjwt - version: 2.10.1 - sha256: dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb - requires_dist: - - cryptography>=3.4.0 ; extra == 'crypto' - - coverage[toml]==5.0.4 ; extra == 'dev' - - cryptography>=3.4.0 ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pytest>=6.0.0,<7.0.0 ; extra == 'dev' - - sphinx ; extra == 'dev' - - sphinx-rtd-theme ; extra == 'dev' - - zope-interface ; extra == 'dev' - - sphinx ; extra == 'docs' - - sphinx-rtd-theme ; extra == 'docs' - - zope-interface ; extra == 'docs' - - coverage[toml]==5.0.4 ; extra == 'tests' - - pytest>=6.0.0,<7.0.0 ; extra == 'tests' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl - name: pytest - version: 8.4.1 - sha256: 539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7 - requires_dist: - - colorama>=0.4 ; sys_platform == 'win32' - - exceptiongroup>=1 ; python_full_version < '3.11' - - iniconfig>=1 - - packaging>=20 - - pluggy>=1.5,<2 - - pygments>=2.7.2 - - tomli>=1 ; python_full_version < '3.11' - - argcomplete ; extra == 'dev' - - attrs>=19.2 ; extra == 'dev' - - hypothesis>=3.56 ; extra == 'dev' - - mock ; extra == 'dev' - - requests ; extra == 'dev' - - setuptools ; extra == 'dev' - - xmlschema ; extra == 'dev' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.11-h9e4cc4f_0_cpython.conda - sha256: 6cca004806ceceea9585d4d655059e951152fc774a471593d4f5138e6a54c81d - md5: 94206474a5608243a10c92cefbe0908f - depends: - - __glibc >=2.17,<3.0.a0 - - bzip2 >=1.0.8,<2.0a0 - - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.7.0,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 - - libgcc >=13 - - liblzma >=5.8.1,<6.0a0 - - libnsl >=2.0.1,<2.1.0a0 - - libsqlite >=3.50.0,<4.0a0 - - libuuid >=2.38.1,<3.0a0 - - libxcrypt >=4.4.36 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.0,<4.0a0 - - readline >=8.2,<9.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - constrains: - - python_abi 3.12.* *_cp312 - license: Python-2.0 - purls: [] - size: 31445023 - timestamp: 1749050216615 -- pypi: https://files.pythonhosted.org/packages/45/3c/b88167e2d6785c0e781ee5d498b07472aeb9b6765da3b19e7cc9e0813841/python_daemon-3.1.2-py3-none-any.whl - name: python-daemon - version: 3.1.2 - sha256: b906833cef63502994ad48e2eab213259ed9bb18d54fa8774dcba2ff7864cec6 - requires_dist: - - lockfile>=0.10 - - pip-check ; extra == 'static-analysis' - - pycodestyle~=2.12 ; extra == 'static-analysis' - - pydocstyle~=6.3 ; extra == 'static-analysis' - - pyupgrade~=3.17 ; extra == 'static-analysis' - - isort~=5.13 ; extra == 'static-analysis' - - python-daemon[doc] ; extra == 'build' - - wheel ; extra == 'build' - - build ; extra == 'build' - - docutils ; extra == 'build' - - changelog-chug ; extra == 'build' - - python-daemon[build,static-analysis] ; extra == 'test' - - testtools ; extra == 'test' - - testscenarios>=0.4 ; extra == 'test' - - coverage ; extra == 'test' - - python-daemon[build] ; extra == 'dist' - - twine ; extra == 'dist' - - python-daemon[dist,test] ; extra == 'devel' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - name: python-dateutil - version: 2.9.0.post0 - sha256: a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 - requires_dist: - - six>=1.5 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' -- pypi: https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl - name: python-dotenv - version: 1.1.1 - sha256: 31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc - requires_dist: - - click>=5.0 ; extra == 'cli' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/08/20/0f2523b9e50a8052bc6a8b732dfc8568abbdc42010aef03a2d750bdab3b2/python_json_logger-3.3.0-py3-none-any.whl - name: python-json-logger - version: 3.3.0 - sha256: dd980fae8cffb24c13caf6e158d3d61c0d6d22342f932cb6e9deedab3d35eec7 - requires_dist: - - typing-extensions ; python_full_version < '3.10' - - orjson ; implementation_name != 'pypy' and extra == 'dev' - - msgspec ; implementation_name != 'pypy' and extra == 'dev' - - validate-pyproject[all] ; extra == 'dev' - - black ; extra == 'dev' - - pylint ; extra == 'dev' - - mypy ; extra == 'dev' - - pytest ; extra == 'dev' - - freezegun ; extra == 'dev' - - backports-zoneinfo ; python_full_version < '3.9' and extra == 'dev' - - tzdata ; extra == 'dev' - - build ; extra == 'dev' - - mkdocs ; extra == 'dev' - - mkdocs-material>=8.5 ; extra == 'dev' - - mkdocs-awesome-pages-plugin ; extra == 'dev' - - mdx-truly-sane-lists ; extra == 'dev' - - mkdocstrings[python] ; extra == 'dev' - - mkdocs-gen-files ; extra == 'dev' - - mkdocs-literate-nav ; extra == 'dev' - - mike ; extra == 'dev' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl - name: python-multipart - version: 0.0.20 - sha256: 8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl - name: python-slugify - version: 8.0.4 - sha256: 276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8 - requires_dist: - - text-unidecode>=1.3 - - unidecode>=1.1.1 ; extra == 'unidecode' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - name: pytz - version: '2025.2' - sha256: 5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 -- pypi: https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: pyyaml - version: 6.0.2 - sha256: 80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/69/9a/9ea7e230feda9400fb0ae0d61d7d6ddda635e718d941c44eeab22a179d34/pyzmq-27.0.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: pyzmq - version: 27.0.0 - sha256: 111db5f395e09f7e775f759d598f43cb815fc58e0147623c4816486e1a39dc22 - requires_dist: - - cffi ; implementation_name == 'pypy' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - sha256: 2d6d0c026902561ed77cd646b5021aef2d4db22e57a5b0178dfc669231e06d2c - md5: 283b96675859b20a825f8fa30f311446 - depends: - - libgcc >=13 - - ncurses >=6.5,<7.0a0 - license: GPL-3.0-only - license_family: GPL - purls: [] - size: 282480 - timestamp: 1740379431762 -- pypi: https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl - name: referencing - version: 0.36.2 - sha256: e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0 - requires_dist: - - attrs>=22.2.0 - - rpds-py>=0.7.0 - - typing-extensions>=4.4.0 ; python_full_version < '3.13' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl - name: requests - version: 2.32.4 - sha256: 27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c - requires_dist: - - charset-normalizer>=2,<4 - - idna>=2.5,<4 - - urllib3>=1.21.1,<3 - - certifi>=2017.4.17 - - pysocks>=1.5.6,!=1.5.7 ; extra == 'socks' - - chardet>=3.0.2,<6 ; extra == 'use-chardet-on-py3' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/b8/09/d5ff873d2579da0082c9afbaad8efde9765aa9bc15875c477fe577f59c09/retryhttp-1.3.3-py3-none-any.whl - name: retryhttp - version: 1.3.3 - sha256: 6b9bd2ba6c9f7eedc73aeb80af97f1f6ebb4cdc71a1b5ec2df6b2f8aa7a2916f - requires_dist: - - httpx - - pydantic - - requests - - types-requests - - tenacity - - httpx ; extra == 'httpx' - - tenacity ; extra == 'httpx' - - requests ; extra == 'requests' - - types-requests ; extra == 'requests' - - tenacity ; extra == 'requests' - - pytest ; extra == 'dev' - - pytest-xdist ; extra == 'dev' - - respx ; extra == 'dev' - - ruff ; extra == 'dev' - - nox ; extra == 'dev' - - types-requests ; extra == 'dev' - - mkdocs ; extra == 'docs' - - mkdocs-material ; extra == 'docs' - - mkdocstrings[python] ; extra == 'docs' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl - name: rfc3339-validator - version: 0.1.4 - sha256: 24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa - requires_dist: - - six - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' -- pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl - name: rfc3986-validator - version: 0.1.1 - sha256: 2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' -- pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl - name: rfc3987-syntax - version: 1.1.0 - sha256: 6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f - requires_dist: - - lark>=1.2.2 - - pytest>=8.3.5 ; extra == 'testing' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl - name: rich - version: 14.0.0 - sha256: 1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0 - requires_dist: - - ipywidgets>=7.5.1,<9 ; extra == 'jupyter' - - markdown-it-py>=2.2.0 - - pygments>=2.13.0,<3.0.0 - - typing-extensions>=4.0.0,<5.0 ; python_full_version < '3.11' - requires_python: '>=3.8.0' -- pypi: https://files.pythonhosted.org/packages/31/f6/5fc0574af5379606ffd57a4b68ed88f9b415eb222047fe023aefcc00a648/rich_argparse-1.7.1-py3-none-any.whl - name: rich-argparse - version: 1.7.1 - sha256: a8650b42e4a4ff72127837632fba6b7da40784842f08d7395eb67a9cbd7b4bf9 - requires_dist: - - rich>=11.0.0 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/78/39/c0fd75955aa963a15c642dfe6fb2acdd1fd2114028ec5ff2e2fd26218ad7/rich_toolkit-0.14.8-py3-none-any.whl - name: rich-toolkit - version: 0.14.8 - sha256: c54bda82b93145a79bbae04c3e15352e6711787c470728ff41fdfa0c2f0c11ae - requires_dist: - - click>=8.1.7 - - rich>=13.7.1 - - typing-extensions>=4.12.2 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/80/c8/b91afda10bd5ca1e3a80463340b899c0dc26a7750a9f3c94f668585c7f40/rignore-0.6.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: rignore - version: 0.6.4 - sha256: 456456802b1e77d1e2d149320ee32505b8183e309e228129950b807d204ddd17 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/2e/77/87d7bfabfc4e821caa35481a2ff6ae0b73e6a391bb6b343db2c91c2b9844/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: rpds-py - version: 0.26.0 - sha256: 82b165b07f416bdccf5c84546a484cc8f15137ca38325403864bfdf2b5b72f6a - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/64/f4/e3cd7f7bda646526f09693e2e02bd83d85fff8a8222c52cf9681c0d30843/ruff-0.12.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: ruff - version: 0.12.4 - sha256: 2abc48f3d9667fdc74022380b5c745873499ff827393a636f7a59da1515e7c57 - requires_python: '>=3.7' -- pypi: ../s2gos-common - name: s2gos-common - version: 0.0.4.dev0 - sha256: 18e640e32d505210d7bb0fbdf5695ca668a41489aa84cc5f41aa4fe658247c77 - requires_dist: - - pydantic - - typer - requires_python: '>=3.10' - editable: true -- pypi: ../s2gos-server - name: s2gos-server - version: 0.0.4.dev0 - sha256: 0df582a16e02468403e2181e136b294dbcfcd062adc4fb7290ffaa97691ee391 - requires_dist: - - fastapi - - pydantic - - pyyaml - - typer - - uvicorn - - s2gos-common>=0.0.0 - requires_python: '>=3.10' - editable: true -- pypi: https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl - name: send2trash - version: 1.8.3 - sha256: 0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9 - requires_dist: - - pyobjc-framework-cocoa ; sys_platform == 'darwin' and extra == 'nativelib' - - pywin32 ; sys_platform == 'win32' and extra == 'nativelib' - - pyobjc-framework-cocoa ; sys_platform == 'darwin' and extra == 'objc' - - pywin32 ; sys_platform == 'win32' and extra == 'win32' - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*' -- pypi: https://files.pythonhosted.org/packages/c2/dc/4d825d5eb6e924dfcc6a91c8185578a7b0a5c41fd2416a6f49c8226d6ef9/sentry_sdk-2.33.2-py2.py3-none-any.whl - name: sentry-sdk - version: 2.33.2 - sha256: 8d57a3b4861b243aa9d558fda75509ad487db14f488cbdb6c78c614979d77632 - requires_dist: - - urllib3>=1.26.11 - - certifi - - aiohttp>=3.5 ; extra == 'aiohttp' - - anthropic>=0.16 ; extra == 'anthropic' - - arq>=0.23 ; extra == 'arq' - - asyncpg>=0.23 ; extra == 'asyncpg' - - apache-beam>=2.12 ; extra == 'beam' - - bottle>=0.12.13 ; extra == 'bottle' - - celery>=3 ; extra == 'celery' - - celery-redbeat>=2 ; extra == 'celery-redbeat' - - chalice>=1.16.0 ; extra == 'chalice' - - clickhouse-driver>=0.2.0 ; extra == 'clickhouse-driver' - - django>=1.8 ; extra == 'django' - - falcon>=1.4 ; extra == 'falcon' - - fastapi>=0.79.0 ; extra == 'fastapi' - - flask>=0.11 ; extra == 'flask' - - blinker>=1.1 ; extra == 'flask' - - markupsafe ; extra == 'flask' - - grpcio>=1.21.1 ; extra == 'grpcio' - - protobuf>=3.8.0 ; extra == 'grpcio' - - httpcore[http2]==1.* ; extra == 'http2' - - httpx>=0.16.0 ; extra == 'httpx' - - huey>=2 ; extra == 'huey' - - huggingface-hub>=0.22 ; extra == 'huggingface-hub' - - langchain>=0.0.210 ; extra == 'langchain' - - launchdarkly-server-sdk>=9.8.0 ; extra == 'launchdarkly' - - litestar>=2.0.0 ; extra == 'litestar' - - loguru>=0.5 ; extra == 'loguru' - - openai>=1.0.0 ; extra == 'openai' - - tiktoken>=0.3.0 ; extra == 'openai' - - openfeature-sdk>=0.7.1 ; extra == 'openfeature' - - opentelemetry-distro>=0.35b0 ; extra == 'opentelemetry' - - opentelemetry-distro ; extra == 'opentelemetry-experimental' - - pure-eval ; extra == 'pure-eval' - - executing ; extra == 'pure-eval' - - asttokens ; extra == 'pure-eval' - - pymongo>=3.1 ; extra == 'pymongo' - - pyspark>=2.4.4 ; extra == 'pyspark' - - quart>=0.16.1 ; extra == 'quart' - - blinker>=1.1 ; extra == 'quart' - - rq>=0.6 ; extra == 'rq' - - sanic>=0.8 ; extra == 'sanic' - - sqlalchemy>=1.2 ; extra == 'sqlalchemy' - - starlette>=0.19.1 ; extra == 'starlette' - - starlite>=1.48 ; extra == 'starlite' - - statsig>=0.55.3 ; extra == 'statsig' - - tornado>=6 ; extra == 'tornado' - - unleashclient>=6.0.1 ; extra == 'unleash' - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/e3/fb/5e9b5068df9e9f31a722a775a5e8322a29a638eaaa3eac5ea7f0b35e6314/setproctitle-1.3.6-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: setproctitle - version: 1.3.6 - sha256: a0d6252098e98129a1decb59b46920d4eca17b0395f3d71b0d327d086fefe77d - requires_dist: - - pytest ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl - name: setuptools - version: 80.9.0 - sha256: 062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 - requires_dist: - - pytest>=6,!=8.1.* ; extra == 'test' - - virtualenv>=13.0.0 ; extra == 'test' - - wheel>=0.44.0 ; extra == 'test' - - pip>=19.1 ; extra == 'test' - - packaging>=24.2 ; extra == 'test' - - jaraco-envs>=2.2 ; extra == 'test' - - pytest-xdist>=3 ; extra == 'test' - - jaraco-path>=3.7.2 ; extra == 'test' - - build[virtualenv]>=1.0.3 ; extra == 'test' - - filelock>=3.4.0 ; extra == 'test' - - ini2toml[lite]>=0.14 ; extra == 'test' - - tomli-w>=1.0.0 ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest-perf ; sys_platform != 'cygwin' and extra == 'test' - - jaraco-develop>=7.21 ; python_full_version >= '3.9' and sys_platform != 'cygwin' and extra == 'test' - - pytest-home>=0.5 ; extra == 'test' - - pytest-subprocess ; extra == 'test' - - pyproject-hooks!=1.1 ; extra == 'test' - - jaraco-test>=5.5 ; extra == 'test' - - sphinx>=3.5 ; extra == 'doc' - - jaraco-packaging>=9.3 ; extra == 'doc' - - rst-linker>=1.9 ; extra == 'doc' - - furo ; extra == 'doc' - - sphinx-lint ; extra == 'doc' - - jaraco-tidelift>=1.4 ; extra == 'doc' - - pygments-github-lexers==0.0.5 ; extra == 'doc' - - sphinx-favicon ; extra == 'doc' - - sphinx-inline-tabs ; extra == 'doc' - - sphinx-reredirects ; extra == 'doc' - - sphinxcontrib-towncrier ; extra == 'doc' - - sphinx-notfound-page>=1,<2 ; extra == 'doc' - - pyproject-hooks!=1.1 ; extra == 'doc' - - towncrier<24.7 ; extra == 'doc' - - packaging>=24.2 ; extra == 'core' - - more-itertools>=8.8 ; extra == 'core' - - jaraco-text>=3.7 ; extra == 'core' - - importlib-metadata>=6 ; python_full_version < '3.10' and extra == 'core' - - tomli>=2.0.1 ; python_full_version < '3.11' and extra == 'core' - - wheel>=0.43.0 ; extra == 'core' - - platformdirs>=4.2.2 ; extra == 'core' - - jaraco-functools>=4 ; extra == 'core' - - more-itertools ; extra == 'core' - - pytest-checkdocs>=2.4 ; extra == 'check' - - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' - - ruff>=0.8.0 ; sys_platform != 'cygwin' and extra == 'check' - - pytest-cov ; extra == 'cover' - - pytest-enabler>=2.2 ; extra == 'enabler' - - pytest-mypy ; extra == 'type' - - mypy==1.14.* ; extra == 'type' - - importlib-metadata>=7.0.2 ; python_full_version < '3.10' and extra == 'type' - - jaraco-develop>=7.21 ; sys_platform != 'cygwin' and extra == 'type' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - name: shellingham - version: 1.5.4 - sha256: 7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - name: six - version: 1.17.0 - sha256: 4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' -- pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - name: sniffio - version: 1.3.1 - sha256: 2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl - name: soupsieve - version: '2.7' - sha256: 6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/c0/8b/f45dd378f6c97e8ff9332ff3d03ecb0b8c491be5bb7a698783b5a2f358ec/SQLAlchemy-1.4.54-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: sqlalchemy - version: 1.4.54 - sha256: b5e0d47d619c739bdc636bbe007da4519fc953393304a5943e0b5aec96c9877c - requires_dist: - - importlib-metadata ; python_full_version < '3.8' - - greenlet!=0.4.17 ; (python_full_version >= '3' and platform_machine == 'AMD64') or (python_full_version >= '3' and platform_machine == 'WIN32') or (python_full_version >= '3' and platform_machine == 'aarch64') or (python_full_version >= '3' and platform_machine == 'amd64') or (python_full_version >= '3' and platform_machine == 'ppc64le') or (python_full_version >= '3' and platform_machine == 'win32') or (python_full_version >= '3' and platform_machine == 'x86_64') - - greenlet!=0.4.17 ; python_full_version >= '3' and extra == 'aiomysql' - - aiomysql>=0.2.0 ; python_full_version >= '3' and extra == 'aiomysql' - - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - - greenlet!=0.4.17 ; python_full_version >= '3' and extra == 'aiosqlite' - - aiosqlite ; python_full_version >= '3' and extra == 'aiosqlite' - - greenlet!=0.4.17 ; python_full_version >= '3' and extra == 'asyncio' - - greenlet!=0.4.17 ; python_full_version >= '3' and extra == 'asyncmy' - - asyncmy>=0.2.3,!=0.2.4 ; python_full_version >= '3' and extra == 'asyncmy' - - mariadb>=1.0.1,!=1.1.2 ; python_full_version >= '3' and extra == 'mariadb-connector' - - mariadb>=1.0.1,!=1.1.2 ; python_full_version >= '3' and extra == 'mariadb-connector' - - pyodbc ; extra == 'mssql' - - pymssql ; extra == 'mssql-pymssql' - - pyodbc ; extra == 'mssql-pyodbc' - - pymssql ; extra == 'mssql-pymssql' - - pyodbc ; extra == 'mssql-pyodbc' - - sqlalchemy2-stubs ; extra == 'mypy' - - mypy>=0.910 ; python_full_version >= '3' and extra == 'mypy' - - mysql-connector-python ; extra == 'mysql-connector' - - mysqlclient>=1.4.0,<2 ; python_full_version < '3' and extra == 'mysql' - - mysqlclient>=1.4.0 ; python_full_version >= '3' and extra == 'mysql' - - mysql-connector-python ; extra == 'mysql-connector' - - cx-oracle>=7,<8 ; python_full_version < '3' and extra == 'oracle' - - cx-oracle>=7 ; python_full_version >= '3' and extra == 'oracle' - - psycopg2>=2.7 ; extra == 'postgresql' - - greenlet!=0.4.17 ; python_full_version >= '3' and extra == 'postgresql-asyncpg' - - asyncpg ; python_full_version >= '3' and extra == 'postgresql-asyncpg' - - pg8000>=1.16.6,!=1.29.0 ; python_full_version >= '3' and extra == 'postgresql-pg8000' - - greenlet!=0.4.17 ; python_full_version >= '3' and extra == 'postgresql-asyncpg' - - asyncpg ; python_full_version >= '3' and extra == 'postgresql-asyncpg' - - pg8000>=1.16.6,!=1.29.0 ; python_full_version >= '3' and extra == 'postgresql-pg8000' - - psycopg2-binary ; extra == 'postgresql-psycopg2binary' - - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' - - pymysql<1 ; python_full_version < '3' and extra == 'pymysql' - - pymysql ; python_full_version >= '3' and extra == 'pymysql' - - sqlcipher3-binary ; python_full_version >= '3' and extra == 'sqlcipher' - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*' -- pypi: https://files.pythonhosted.org/packages/fd/67/d75d119e70863e0519c8eec5fc66714d34ad1ee9e5e73bf4fc8e3d259fac/SQLAlchemy_JSONField-1.0.2-py3-none-any.whl - name: sqlalchemy-jsonfield - version: 1.0.2 - sha256: b2945fa1e60b07d5764a7c73b18da427948b35dd4c07c0e94939001dc2dacf77 - requires_dist: - - sqlalchemy - requires_python: '>=3.7.0' -- pypi: https://files.pythonhosted.org/packages/d5/f0/dc4757b83ac1ab853cf222df8535ed73973e0c203d983982ba7b8bc60508/SQLAlchemy_Utils-0.41.2-py3-none-any.whl - name: sqlalchemy-utils - version: 0.41.2 - sha256: 85cf3842da2bf060760f955f8467b87983fb2e30f1764fd0e24a48307dc8ec6e - requires_dist: - - sqlalchemy>=1.3 - - importlib-metadata ; python_full_version < '3.8' - - arrow>=0.3.4 ; extra == 'arrow' - - babel>=1.3 ; extra == 'babel' - - colour>=0.0.4 ; extra == 'color' - - cryptography>=0.6 ; extra == 'encrypted' - - intervals>=0.7.1 ; extra == 'intervals' - - passlib>=1.6,<2.0 ; extra == 'password' - - pendulum>=2.0.5 ; extra == 'pendulum' - - phonenumbers>=5.9.2 ; extra == 'phone' - - pytest==7.4.4 ; extra == 'test' - - pygments>=1.2 ; extra == 'test' - - jinja2>=2.3 ; extra == 'test' - - docutils>=0.10 ; extra == 'test' - - flexmock>=0.9.7 ; extra == 'test' - - psycopg>=3.1.8 ; extra == 'test' - - psycopg2>=2.5.1 ; extra == 'test' - - psycopg2cffi>=2.8.1 ; extra == 'test' - - pg8000>=1.12.4 ; extra == 'test' - - pytz>=2014.2 ; extra == 'test' - - python-dateutil>=2.6 ; extra == 'test' - - pymysql ; extra == 'test' - - flake8>=2.4.0 ; extra == 'test' - - isort>=4.2.2 ; extra == 'test' - - pyodbc ; extra == 'test' - - backports-zoneinfo ; python_full_version < '3.9' and extra == 'test' - - babel>=1.3 ; extra == 'test-all' - - jinja2>=2.3 ; extra == 'test-all' - - pygments>=1.2 ; extra == 'test-all' - - arrow>=0.3.4 ; extra == 'test-all' - - colour>=0.0.4 ; extra == 'test-all' - - cryptography>=0.6 ; extra == 'test-all' - - docutils>=0.10 ; extra == 'test-all' - - flake8>=2.4.0 ; extra == 'test-all' - - flexmock>=0.9.7 ; extra == 'test-all' - - furl>=0.4.1 ; extra == 'test-all' - - intervals>=0.7.1 ; extra == 'test-all' - - isort>=4.2.2 ; extra == 'test-all' - - passlib>=1.6,<2.0 ; extra == 'test-all' - - pendulum>=2.0.5 ; extra == 'test-all' - - pg8000>=1.12.4 ; extra == 'test-all' - - phonenumbers>=5.9.2 ; extra == 'test-all' - - psycopg2>=2.5.1 ; extra == 'test-all' - - psycopg2cffi>=2.8.1 ; extra == 'test-all' - - psycopg>=3.1.8 ; extra == 'test-all' - - pymysql ; extra == 'test-all' - - pyodbc ; extra == 'test-all' - - pytest==7.4.4 ; extra == 'test-all' - - python-dateutil ; extra == 'test-all' - - python-dateutil>=2.6 ; extra == 'test-all' - - pytz>=2014.2 ; extra == 'test-all' - - backports-zoneinfo ; python_full_version < '3.9' and extra == 'test-all' - - python-dateutil ; extra == 'timezone' - - furl>=0.4.1 ; extra == 'url' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl - name: sqlparse - version: 0.5.3 - sha256: cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca - requires_dist: - - build ; extra == 'dev' - - hatch ; extra == 'dev' - - sphinx ; extra == 'doc' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl - name: stack-data - version: 0.6.3 - sha256: d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695 - requires_dist: - - executing>=1.2.0 - - asttokens>=2.1.0 - - pure-eval - - pytest ; extra == 'tests' - - typeguard ; extra == 'tests' - - pygments ; extra == 'tests' - - littleutils ; extra == 'tests' - - cython ; extra == 'tests' -- pypi: https://files.pythonhosted.org/packages/f7/1f/b876b1f83aef204198a42dc101613fefccb32258e5428b5f9259677864b4/starlette-0.47.2-py3-none-any.whl - name: starlette - version: 0.47.2 - sha256: c5847e96134e5c5371ee9fac6fdf1a67336d5815e09eb2a01fdb57a351ef915b - requires_dist: - - anyio>=3.6.2,<5 - - typing-extensions>=4.10.0 ; python_full_version < '3.13' - - httpx>=0.27.0,<0.29.0 ; extra == 'full' - - itsdangerous ; extra == 'full' - - jinja2 ; extra == 'full' - - python-multipart>=0.0.18 ; extra == 'full' - - pyyaml ; extra == 'full' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a0/4a/97ee6973e3a73c74c8120d59829c3861ea52210667ec3e7a16045c62b64d/structlog-25.4.0-py3-none-any.whl - name: structlog - version: 25.4.0 - sha256: fe809ff5c27e557d14e613f45ca441aabda051d119ee5a0102aaba6ce40eed2c - requires_dist: - - typing-extensions ; python_full_version < '3.11' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/a2/1c/a6b5d90a9ca479805798276728ccbbdff0c7228e2ea93b1f731779d635e3/svcs-25.1.0-py3-none-any.whl - name: svcs - version: 25.1.0 - sha256: df49cb7d1a05dfd2dd60af1a2cb84b9c3bb0a74728833cb8c54a7ceeecce6c97 - requires_dist: - - attrs>=21.3.0 - - aiohttp ; extra == 'dev' - - fastapi ; extra == 'dev' - - flask ; extra == 'dev' - - httpx ; extra == 'dev' - - mypy>=1.4 ; extra == 'dev' - - pyramid ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-asyncio ; extra == 'dev' - - starlette ; extra == 'dev' - - sybil>=6 ; extra == 'dev' - - tox-uv ; extra == 'dev' - - tox>4 ; extra == 'dev' - - aiohttp ; extra == 'docs' - - fastapi ; extra == 'docs' - - flask ; extra == 'docs' - - furo>=2023.8.17 ; extra == 'docs' - - httpx ; extra == 'docs' - - myst-parser ; extra == 'docs' - - pyramid ; extra == 'docs' - - pytest ; extra == 'docs' - - pytest-asyncio ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx-design ; extra == 'docs' - - sphinx-notfound-page ; extra == 'docs' - - sphinx>=7.2.2 ; extra == 'docs' - - sphinxext-opengraph ; extra == 'docs' - - sqlalchemy ; extra == 'docs' - - starlette ; extra == 'docs' - - sybil ; extra == 'docs' - - pytest ; extra == 'tests' - - pytest-asyncio ; extra == 'tests' - - sybil>=6 ; extra == 'tests' - - aiohttp ; extra == 'typing' - - fastapi ; extra == 'typing' - - flask ; extra == 'typing' - - mypy>=1.4 ; extra == 'typing' - - pyramid ; extra == 'typing' - - starlette ; extra == 'typing' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl - name: tabulate - version: 0.9.0 - sha256: 024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f - requires_dist: - - wcwidth ; extra == 'widechars' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl - name: tenacity - version: 9.1.2 - sha256: f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138 - requires_dist: - - reno ; extra == 'doc' - - sphinx ; extra == 'doc' - - pytest ; extra == 'test' - - tornado>=4.5 ; extra == 'test' - - typeguard ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/4f/bd/de8d508070629b6d84a30d01d57e4a65c69aa7f5abe7560b8fad3b50ea59/termcolor-3.1.0-py3-none-any.whl - name: termcolor - version: 3.1.0 - sha256: 591dd26b5c2ce03b9e43f391264626557873ce1d379019786f99b0c2bee140aa - requires_dist: - - pytest ; extra == 'tests' - - pytest-cov ; extra == 'tests' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl - name: terminado - version: 0.18.1 - sha256: a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0 - requires_dist: - - ptyprocess ; os_name != 'nt' - - pywinpty>=1.1.0 ; os_name == 'nt' - - tornado>=6.1.0 - - myst-parser ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - sphinx ; extra == 'docs' - - pre-commit ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest>=7.0 ; extra == 'test' - - mypy~=1.6 ; extra == 'typing' - - traitlets>=5.11.1 ; extra == 'typing' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl - name: text-unidecode - version: '1.3' - sha256: 1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8 -- pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl - name: tinycss2 - version: 1.4.0 - sha256: 3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289 - requires_dist: - - webencodings>=0.4 - - sphinx ; extra == 'doc' - - sphinx-rtd-theme ; extra == 'doc' - - pytest ; extra == 'test' - - ruff ; extra == 'test' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda - sha256: a84ff687119e6d8752346d1d408d5cf360dee0badd487a472aa8ddedfdc219e1 - md5: a0116df4f4ed05c303811a837d5b39d8 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libzlib >=1.3.1,<2.0a0 - license: TCL - license_family: BSD - purls: [] - size: 3285204 - timestamp: 1748387766691 -- pypi: https://files.pythonhosted.org/packages/7d/f7/0c48ba992d875521ac761e6e04b0a1750f8150ae42ea26df1852d6a98942/tornado-6.5.1-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: tornado - version: 6.5.1 - sha256: 308473f4cc5a76227157cdf904de33ac268af770b2c5f05ca6c1161d82fdd95e - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl - name: traitlets - version: 5.14.3 - sha256: b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f - requires_dist: - - myst-parser ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - sphinx ; extra == 'docs' - - argcomplete>=3.0.3 ; extra == 'test' - - mypy>=1.7.0 ; extra == 'test' - - pre-commit ; extra == 'test' - - pytest-mock ; extra == 'test' - - pytest-mypy-testing ; extra == 'test' - - pytest>=7.0,<8.2 ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/76/42/3efaf858001d2c2913de7f354563e3a3a2f0decae3efe98427125a8f441e/typer-0.16.0-py3-none-any.whl - name: typer - version: 0.16.0 - sha256: 1f79bed11d4d02d4310e3c1b7ba594183bcedb0ac73b27a9e5f28f6fb5b98855 - requires_dist: - - click>=8.0.0 - - typing-extensions>=3.7.4.3 - - shellingham>=1.3.0 - - rich>=10.11.0 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/72/52/43e70a8e57fefb172c22a21000b03ebcc15e47e97f5cb8495b9c2832efb4/types_python_dateutil-2.9.0.20250708-py3-none-any.whl - name: types-python-dateutil - version: 2.9.0.20250708 - sha256: 4d6d0cc1cc4d24a2dc3816024e502564094497b713f7befda4d5bc7a8e3fd21f - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3d/ea/0be9258c5a4fa1ba2300111aa5a0767ee6d18eb3fd20e91616c12082284d/types_requests-2.32.4.20250611-py3-none-any.whl - name: types-requests - version: 2.32.4.20250611 - sha256: ad2fe5d3b0cb3c2c902c8815a70e7fb2302c4b8c1f77bdcd738192cdb3878072 - requires_dist: - - urllib3>=2 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl - name: typing-extensions - version: 4.14.1 - sha256: d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl - name: typing-inspection - version: 0.4.1 - sha256: 389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51 - requires_dist: - - typing-extensions>=4.12.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl - name: tzdata - version: '2025.2' - sha256: 1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8 - requires_python: '>=2' -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - sha256: 5aaa366385d716557e365f0a4e9c3fca43ba196872abbbe3d56bb610d131e192 - md5: 4222072737ccff51314b5ece9c7d6f5a - license: LicenseRef-Public-Domain - purls: [] - size: 122968 - timestamp: 1742727099393 -- pypi: https://files.pythonhosted.org/packages/37/87/1f677586e8ac487e29672e4b17455758fce261de06a0d086167bb760361a/uc_micro_py-1.0.3-py3-none-any.whl - name: uc-micro-py - version: 1.0.3 - sha256: db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5 - requires_dist: - - pytest ; extra == 'test' - - coverage ; extra == 'test' - - pytest-cov ; extra == 'test' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/e5/4d/2e577f6db7aa0f932d19f799c18f604b2b302c65f733419b900ec07dbade/universal_pathlib-0.2.6-py3-none-any.whl - name: universal-pathlib - version: 0.2.6 - sha256: 700dec2b58ef34b87998513de6d2ae153b22f083197dfafb8544744edabd1b18 - requires_dist: - - fsspec>=2022.1.0,!=2024.3.1 - - pytest>=8 ; extra == 'tests' - - pytest-sugar>=0.9.7 ; extra == 'tests' - - pytest-cov>=4.1.0 ; extra == 'tests' - - pytest-mock>=3.12.0 ; extra == 'tests' - - pylint>=2.17.4 ; extra == 'tests' - - mypy>=1.10.0 ; extra == 'tests' - - pytest-mypy-plugins>=3.1.2 ; extra == 'tests' - - packaging ; extra == 'tests' - - adlfs ; extra == 'dev' - - aiohttp ; extra == 'dev' - - requests ; extra == 'dev' - - gcsfs ; extra == 'dev' - - s3fs ; extra == 'dev' - - moto[s3,server] ; extra == 'dev' - - webdav4[fsspec] ; extra == 'dev' - - paramiko ; extra == 'dev' - - wsgidav ; extra == 'dev' - - cheroot ; extra == 'dev' - - pydantic ; extra == 'dev' - - pydantic-settings ; extra == 'dev' - - smbprotocol ; extra == 'dev' - - typing-extensions ; python_full_version < '3.11' and extra == 'dev' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl - name: uri-template - version: 1.3.0 - sha256: a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363 - requires_dist: - - types-pyyaml ; extra == 'dev' - - mypy ; extra == 'dev' - - flake8 ; extra == 'dev' - - flake8-annotations ; extra == 'dev' - - flake8-bandit ; extra == 'dev' - - flake8-bugbear ; extra == 'dev' - - flake8-commas ; extra == 'dev' - - flake8-comprehensions ; extra == 'dev' - - flake8-continuation ; extra == 'dev' - - flake8-datetimez ; extra == 'dev' - - flake8-docstrings ; extra == 'dev' - - flake8-import-order ; extra == 'dev' - - flake8-literal ; extra == 'dev' - - flake8-modern-annotations ; extra == 'dev' - - flake8-noqa ; extra == 'dev' - - flake8-pyproject ; extra == 'dev' - - flake8-requirements ; extra == 'dev' - - flake8-typechecking-import ; extra == 'dev' - - flake8-use-fstring ; extra == 'dev' - - pep8-naming ; extra == 'dev' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl - name: urllib3 - version: 2.5.0 - sha256: e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc - requires_dist: - - brotli>=1.0.9 ; platform_python_implementation == 'CPython' and extra == 'brotli' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'brotli' - - h2>=4,<5 ; extra == 'h2' - - pysocks>=1.5.6,!=1.5.7,<2.0 ; extra == 'socks' - - zstandard>=0.18.0 ; extra == 'zstd' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3d/b2/93faaab7962e2aa8d6e174afb6f76be2ca0ce89fde14d3af835acebcaa59/uuid6-2025.0.1-py3-none-any.whl - name: uuid6 - version: 2025.0.1 - sha256: 80530ce4d02a93cdf82e7122ca0da3ebbbc269790ec1cb902481fa3e9cc9ff99 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d2/e2/dc81b1bd1dcfe91735810265e9d26bc8ec5da45b4c0f6237e286819194c3/uvicorn-0.35.0-py3-none-any.whl - name: uvicorn - version: 0.35.0 - sha256: 197535216b25ff9b785e29a0b79199f55222193d47f820816e7da751e9bc8d4a - requires_dist: - - click>=7.0 - - h11>=0.8 - - typing-extensions>=4.0 ; python_full_version < '3.11' - - colorama>=0.4 ; sys_platform == 'win32' and extra == 'standard' - - httptools>=0.6.3 ; extra == 'standard' - - python-dotenv>=0.13 ; extra == 'standard' - - pyyaml>=5.1 ; extra == 'standard' - - uvloop>=0.15.1 ; platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32' and extra == 'standard' - - watchfiles>=0.13 ; extra == 'standard' - - websockets>=10.4 ; extra == 'standard' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/06/a7/b4e6a19925c900be9f98bec0a75e6e8f79bb53bdeb891916609ab3958967/uvloop-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: uvloop - version: 0.21.0 - sha256: 86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc - requires_dist: - - setuptools>=60 ; extra == 'dev' - - cython~=3.0 ; extra == 'dev' - - sphinx~=4.1.2 ; extra == 'docs' - - sphinxcontrib-asyncio~=0.3.0 ; extra == 'docs' - - sphinx-rtd-theme~=0.5.2 ; extra == 'docs' - - aiohttp>=3.10.5 ; extra == 'test' - - flake8~=5.0 ; extra == 'test' - - psutil ; extra == 'test' - - pycodestyle~=2.9.0 ; extra == 'test' - - pyopenssl~=23.0.0 ; extra == 'test' - - mypy>=0.800 ; extra == 'test' - requires_python: '>=3.8.0' -- pypi: https://files.pythonhosted.org/packages/8c/77/e3362fe308358dc9f8588102481e599c83e1b91c2ae843780a7ded939a35/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: watchfiles - version: 1.1.0 - sha256: f7590d5a455321e53857892ab8879dce62d1f4b04748769f5adf2e707afb9d4f - requires_dist: - - anyio>=3.0.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl - name: wcwidth - version: 0.2.13 - sha256: 3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859 - requires_dist: - - backports-functools-lru-cache>=1.2.1 ; python_full_version < '3.2' -- pypi: https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl - name: webcolors - version: 24.11.1 - sha256: 515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl - name: webencodings - version: 0.5.1 - sha256: a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 -- pypi: https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl - name: websocket-client - version: 1.8.0 - sha256: 17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526 - requires_dist: - - sphinx>=6.0 ; extra == 'docs' - - sphinx-rtd-theme>=1.1.0 ; extra == 'docs' - - myst-parser>=2.0.0 ; extra == 'docs' - - python-socks ; extra == 'optional' - - wsaccel ; extra == 'optional' - - websockets ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: websockets - version: 15.0.1 - sha256: 64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl - name: werkzeug - version: 3.1.3 - sha256: 54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e - requires_dist: - - markupsafe>=2.1.1 - - watchdog>=2.3 ; extra == 'watchdog' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ca/51/5447876806d1088a0f8f71e16542bf350918128d0a69437df26047c8e46f/widgetsnbextension-4.0.14-py3-none-any.whl - name: widgetsnbextension - version: 4.0.14 - sha256: 4875a9eaf72fbf5079dc372a51a9f268fc38d46f767cbf85c43a36da5cb9b575 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/42/2d/3557ee32d8268b04ce8aada3212b0d49f2ddcf86dc200f3999a772262dc5/wirerope-1.0.0-py2.py3-none-any.whl - name: wirerope - version: 1.0.0 - sha256: 59346555c7b5dbd1c683a4e123f8bed30ca99df646f6867ea6439ceabf43c2f6 - requires_dist: - - six>=1.11.0 - - inspect2>=0.1.0 ; python_full_version < '3' - - singledispatch>=3.4.0.3 ; python_full_version < '3.4' - - pytest>=4.6.7 ; extra == 'test' - - pytest-cov>=2.6.1 ; extra == 'test' - - pytest-checkdocs>=1.2.5 ; python_full_version < '3' and extra == 'test' - - pytest-checkdocs>=2.9.0 ; python_full_version >= '3' and extra == 'test' - - sphinx ; extra == 'doc' -- pypi: https://files.pythonhosted.org/packages/2a/5a/04cde32b07a7431d4ed0553a76fdb7a61270e78c5fd5a603e190ac389f14/wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: wrapt - version: 1.17.2 - sha256: bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/b2/ea/9554e5fb78eda4dbc9e9ccaf23034166fe3e9ea9af82ea6204b9578434bc/xarray-2025.7.1-py3-none-any.whl - name: xarray - version: 2025.7.1 - sha256: e8647b659e53bd350d7c5a91c34dd4122ad6a3ca0bc41399d424a7c0273c7635 - requires_dist: - - numpy>=1.26 - - packaging>=24.1 - - pandas>=2.2 - - scipy>=1.13 ; extra == 'accel' - - bottleneck ; extra == 'accel' - - numbagg>=0.8 ; extra == 'accel' - - numba>=0.59 ; extra == 'accel' - - flox>=0.9 ; extra == 'accel' - - opt-einsum ; extra == 'accel' - - xarray[accel,etc,io,parallel,viz] ; extra == 'complete' - - netcdf4>=1.6.0 ; extra == 'io' - - h5netcdf ; extra == 'io' - - pydap ; extra == 'io' - - scipy>=1.13 ; extra == 'io' - - zarr>=2.18 ; extra == 'io' - - fsspec ; extra == 'io' - - cftime ; extra == 'io' - - pooch ; extra == 'io' - - sparse>=0.15 ; extra == 'etc' - - dask[complete] ; extra == 'parallel' - - cartopy>=0.23 ; extra == 'viz' - - matplotlib ; extra == 'viz' - - nc-time-axis ; extra == 'viz' - - seaborn ; extra == 'viz' - - pandas-stubs ; extra == 'types' - - scipy-stubs ; extra == 'types' - - types-pyyaml ; extra == 'types' - - types-pygments ; extra == 'types' - - types-colorama ; extra == 'types' - - types-decorator ; extra == 'types' - - types-defusedxml ; extra == 'types' - - types-docutils ; extra == 'types' - - types-networkx ; extra == 'types' - - types-pexpect ; extra == 'types' - - types-psutil ; extra == 'types' - - types-pycurl ; extra == 'types' - - types-openpyxl ; extra == 'types' - - types-python-dateutil ; extra == 'types' - - types-pytz ; extra == 'types' - - types-setuptools ; extra == 'types' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl - name: zarr - version: 3.1.0 - sha256: bd3d2f88d602d43f81df82e26dd115ea66635a2af5bf6da261d3c640bb4c1ce4 - requires_dist: - - donfig>=0.8 - - numcodecs[crc32c]>=0.14 - - numpy>=1.26 - - packaging>=22.0 - - typing-extensions>=4.9 - - astroid<4 ; extra == 'docs' - - numcodecs[msgpack] ; extra == 'docs' - - numpydoc ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - pytest ; extra == 'docs' - - rich ; extra == 'docs' - - s3fs>=2023.10.0 ; extra == 'docs' - - sphinx-autoapi==3.4.0 ; extra == 'docs' - - sphinx-autobuild>=2021.3.14 ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx-design ; extra == 'docs' - - sphinx-issues ; extra == 'docs' - - sphinx-reredirects ; extra == 'docs' - - sphinx==8.1.3 ; extra == 'docs' - - towncrier ; extra == 'docs' - - cupy-cuda12x ; extra == 'gpu' - - rich ; extra == 'optional' - - universal-pathlib ; extra == 'optional' - - fsspec>=2023.10.0 ; extra == 'remote' - - obstore>=0.5.1 ; extra == 'remote' - - botocore ; extra == 'remote-tests' - - fsspec>=2023.10.0 ; extra == 'remote-tests' - - moto[s3,server] ; extra == 'remote-tests' - - obstore>=0.5.1 ; extra == 'remote-tests' - - requests ; extra == 'remote-tests' - - s3fs>=2023.10.0 ; extra == 'remote-tests' - - coverage ; extra == 'test' - - hypothesis ; extra == 'test' - - mypy ; extra == 'test' - - packaging ; extra == 'test' - - pytest-accept ; extra == 'test' - - pytest-asyncio ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-xdist ; extra == 'test' - - pytest<8.4 ; extra == 'test' - - rich ; extra == 'test' - - tomlkit ; extra == 'test' - - uv ; extra == 'test' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - name: zipp - version: 3.23.0 - sha256: 071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e - requires_dist: - - pytest>=6,!=8.1.* ; extra == 'test' - - jaraco-itertools ; extra == 'test' - - jaraco-functools ; extra == 'test' - - more-itertools ; extra == 'test' - - big-o ; extra == 'test' - - pytest-ignore-flaky ; extra == 'test' - - jaraco-test ; extra == 'test' - - sphinx>=3.5 ; extra == 'doc' - - jaraco-packaging>=9.3 ; extra == 'doc' - - rst-linker>=1.9 ; extra == 'doc' - - furo ; extra == 'doc' - - sphinx-lint ; extra == 'doc' - - jaraco-tidelift>=1.4 ; extra == 'doc' - - pytest-checkdocs>=2.4 ; extra == 'check' - - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' - - pytest-cov ; extra == 'cover' - - pytest-enabler>=2.2 ; extra == 'enabler' - - pytest-mypy ; extra == 'type' - requires_python: '>=3.9' diff --git a/s2gos-airflow/pyproject.toml b/s2gos-airflow/pyproject.toml deleted file mode 100644 index 807b395..0000000 --- a/s2gos-airflow/pyproject.toml +++ /dev/null @@ -1,53 +0,0 @@ -[project] -name = "s2gos-airflow" -version = "0.0.0" -description = "Airflow DAGs for the ESA DTE-S2GOS synthetic scene generator service" -requires-python = "==3.12" - -#### pixi ################### - -[tool.pixi.activation.env] -AIRFLOW_HOME="$PIXI_PROJECT_ROOT/.airflow" -AIRFLOW__CORE__LOAD_EXAMPLES="False" -AIRFLOW__CORE__DAGS_FOLDER="$PIXI_PROJECT_ROOT/dags" - -[tool.pixi.project] -channels = ["conda-forge"] -platforms = ["linux-64"] - -[tool.pixi.dependencies] -python = "3.12.*" - -[tool.pixi.pypi-dependencies] -# Airflow -apache-airflow = "==3.0.2" -# S2GOS service implementation -s2gos-common = { path = "../s2gos-common", editable = true } -s2gos-server = { path = "../s2gos-server", editable = true } -fastapi = "*" -pydantic = "*" -pyyaml = "*" -typer = "*" -uvicorn = "*" -# DAG testing -jupyter = "*" -pandas = "*" -xarray = "*" -zarr = "*" -# Dev tools -isort = "*" -mypy = "*" -pytest = "*" -ruff = "*" - -[tool.pixi.tasks] -install-airflow = """ -export AIRFLOW_VERSION=3.0.2 -export PYTHON_VERSION=$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') -pip install "apache-airflow==$AIRFLOW_VERSION" \\ - --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-$AIRFLOW_VERSION/constraints-no-providers-$PYTHON_VERSION.txt" -""" -test = "pytest tests" -format = "isort dags && ruff format dags" -check = "ruff check dags" -typecheck = "mypy dags" diff --git a/s2gos-airflow/tests/dags/__init__.py b/s2gos-airflow/tests/dags/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-airflow/tests/dags/test_example_dag.py b/s2gos-airflow/tests/dags/test_example_dag.py deleted file mode 100644 index d862a97..0000000 --- a/s2gos-airflow/tests/dags/test_example_dag.py +++ /dev/null @@ -1,8 +0,0 @@ -from airflow.models import DagBag - - -def test_dag_loads(): - dagbag = DagBag() - dag = dagbag.get_dag("S2GOS-Example-DAG") - assert dag is not None - assert dag.dag_id == "S2GOS-Example-DAG" \ No newline at end of file diff --git a/s2gos-airflow/tests/test_airflow_service.py b/s2gos-airflow/tests/test_airflow_service.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-app-ex/Dockerfile b/s2gos-app-ex/Dockerfile deleted file mode 100644 index d19be98..0000000 --- a/s2gos-app-ex/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -# Stage 1 --------------------------- -FROM ghcr.io/prefix-dev/pixi:0.50.2-bookworm-slim AS build -WORKDIR /app -RUN mkdir s2gos-app-ex -COPY ./s2gos-app-ex ./s2gos-app-ex -RUN cd ./s2gos-app-ex && pixi install --locked -e production -RUN cd ./s2gos-app-ex && pixi shell-hook -e production -s bash > /shell-hook -RUN echo "#!/bin/bash" > /app/entrypoint.sh -RUN cat /shell-hook >> /app/entrypoint.sh -RUN echo 'exec "$@"' >> /app/entrypoint.sh - -# Stage 2 --------------------------- -FROM ubuntu:24.04 AS production -WORKDIR /app -COPY --from=build /app/s2gos-app-ex/.pixi/envs/production /app/s2gos-app-ex/.pixi/envs/production -COPY --from=build /app/s2gos-app-ex/src /app/s2gos-app-ex/src -COPY --from=build --chmod=0755 /app/entrypoint.sh /app/entrypoint.sh -ENTRYPOINT [ "/app/entrypoint.sh" ] diff --git a/s2gos-app-ex/LICENSE b/s2gos-app-ex/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/s2gos-app-ex/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/s2gos-app-ex/README.md b/s2gos-app-ex/README.md deleted file mode 100644 index b28bc62..0000000 --- a/s2gos-app-ex/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# DTE-S2GOS application example - -Build and run the image - -```commandline -cd .. -docker build -f s2gos-app-ex/Dockerfile -t s2gos-app-ex-v1 . -docker run s2gos-app-ex-v1 s2gos-app-ex --help -docker run -it s2gos-app-ex-v1 /bin/bash -``` diff --git a/s2gos-app-ex/pixi.lock b/s2gos-app-ex/pixi.lock deleted file mode 100644 index ebce1a0..0000000 --- a/s2gos-app-ex/pixi.lock +++ /dev/null @@ -1,1222 +0,0 @@ -version: 6 -environments: - default: - channels: - - url: https://conda.anaconda.org/conda-forge/ - indexes: - - https://pypi.org/simple - packages: - linux-64: - - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.10.1-py312h8a5da7c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/isort-6.0.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1423503_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.3-hee844dc_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.17.0-py312h4c3975b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.1-h7b32b05_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.0.0-py312h66e93f0_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.33.2-py312h680f630_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.11-h9e4cc4f_0_cpython.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-8_cp312.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.1.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.12.5-hf9daec2_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhe01879c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.16.0-pyh167b9f4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.16.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.16.0-hf964461_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.14.1-h4440ef1_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.1-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - pypi: https://files.pythonhosted.org/packages/8a/6d/f596954df87cfa05b82a9f7f2bbda486b40465378c978998f06058eecdfa/gavicore-0.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/35/53/f31ab23c29a5a25084948774ee4a43d02d8b1076e8498de9152afda62768/procodile-0.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: ./ - win-64: - - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-h4c7d964_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh7428d3b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.10.1-py312h05f76fc_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/isort-6.0.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.1-hac47afa_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.50.4-hf5d6505_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.17.1-py312he06e257_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.5.1-h725018a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.0.0-py312h4389bb4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.33.2-py312h8422cdd_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.12.11-h3f84c4b_0_cpython.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-8_cp312.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.1.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.12.7-hd40eec1_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhe01879c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.16.0-pyh167b9f4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.16.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.16.0-hf964461_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.14.1-h4440ef1_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.1-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_31.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_31.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_31.conda - - pypi: https://files.pythonhosted.org/packages/8a/6d/f596954df87cfa05b82a9f7f2bbda486b40465378c978998f06058eecdfa/gavicore-0.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/35/53/f31ab23c29a5a25084948774ee4a43d02d8b1076e8498de9152afda62768/procodile-0.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl - - pypi: ./ - production: - channels: - - url: https://conda.anaconda.org/conda-forge/ - indexes: - - https://pypi.org/simple - packages: - linux-64: - - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1423503_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.3-hee844dc_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.1-h7b32b05_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.33.2-py312h680f630_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.11-h9e4cc4f_0_cpython.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-8_cp312.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.1.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.16.0-pyh167b9f4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.16.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.16.0-hf964461_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.14.1-h4440ef1_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.1-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - pypi: https://files.pythonhosted.org/packages/8a/6d/f596954df87cfa05b82a9f7f2bbda486b40465378c978998f06058eecdfa/gavicore-0.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/35/53/f31ab23c29a5a25084948774ee4a43d02d8b1076e8498de9152afda62768/procodile-0.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: ./ - win-64: - - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-h4c7d964_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh7428d3b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.1-hac47afa_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.50.4-hf5d6505_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.5.1-h725018a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.33.2-py312h8422cdd_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.12.11-h3f84c4b_0_cpython.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-8_cp312.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.1.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.16.0-pyh167b9f4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.16.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.16.0-hf964461_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.14.1-h4440ef1_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.1-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_31.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_31.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_31.conda - - pypi: https://files.pythonhosted.org/packages/8a/6d/f596954df87cfa05b82a9f7f2bbda486b40465378c978998f06058eecdfa/gavicore-0.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/35/53/f31ab23c29a5a25084948774ee4a43d02d8b1076e8498de9152afda62768/procodile-0.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl - - pypi: ./ -packages: -- conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 - md5: d7c89558ba9fa0495403155b64376d81 - license: None - purls: [] - size: 2562 - timestamp: 1578324546067 -- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - build_number: 16 - sha256: fbe2c5e56a653bebb982eda4876a9178aedfc2b545f25d0ce9c4c0b508253d22 - md5: 73aaf86a425cc6e73fcf236a5a46396d - depends: - - _libgcc_mutex 0.1 conda_forge - - libgomp >=7.5.0 - constrains: - - openmp_impl 9999 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 23621 - timestamp: 1650670423406 -- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 - md5: 2934f256a8acfe48f6ebb4fce6cde29c - depends: - - python >=3.9 - - typing-extensions >=4.0.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/annotated-types?source=hash-mapping - size: 18074 - timestamp: 1733247158254 -- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - sha256: 5ced96500d945fb286c9c838e54fa759aa04a7129c59800f0846b4335cee770d - md5: 62ee74e96c5ebb0af99386de58cf9553 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - license: bzip2-1.0.6 - license_family: BSD - purls: [] - size: 252783 - timestamp: 1720974456583 -- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda - sha256: 35a5dad92e88fdd7fc405e864ec239486f4f31eec229e31686e61a140a8e573b - md5: 276e7ffe9ffe39688abc665ef0f45596 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: bzip2-1.0.6 - license_family: BSD - purls: [] - size: 54927 - timestamp: 1720974860185 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-h4c7d964_0.conda - sha256: a7fe9bce8a0f9f985d44940ec13a297df571ee70fb2264b339c62fa190b2c437 - md5: 40334594f5916bc4c0a0313d64bfe046 - depends: - - __win - license: ISC - purls: [] - size: 155882 - timestamp: 1752482396143 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda - sha256: 29defbd83c7829788358678ec996adeee252fa4d4274b7cd386c1ed73d2b201e - md5: d16c90324aef024877d8713c0b7fea5b - depends: - - __unix - license: ISC - purls: [] - size: 155658 - timestamp: 1752482350666 -- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda - sha256: 8aee789c82d8fdd997840c952a586db63c6890b00e88c4fb6e80a38edd5f51c0 - md5: 94b550b8d3a614dbd326af798c7dfb40 - depends: - - __unix - - python >=3.10 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/click?source=hash-mapping - size: 87749 - timestamp: 1747811451319 -- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh7428d3b_0.conda - sha256: 20c2d8ea3d800485245b586a28985cba281dd6761113a49d7576f6db92a0a891 - md5: 3a59475037bc09da916e4062c5cad771 - depends: - - __win - - colorama - - python >=3.10 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/click?source=hash-mapping - size: 88117 - timestamp: 1747811467132 -- conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287 - md5: 962b9857ee8e7018c22f2776ffa0b2d7 - depends: - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/colorama?source=hash-mapping - size: 27011 - timestamp: 1733218222191 -- conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.10.1-py312h8a5da7c_0.conda - sha256: ec4574e012597c73a49681fab4da8516a3582da019374a3826ab2e34d5568ac6 - md5: 712f11dddb6b50bce51ed11a73b6d9c2 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.12,<3.13.0a0 - - python_abi 3.12.* *_cp312 - - tomli - license: Apache-2.0 - purls: - - pkg:pypi/coverage?source=hash-mapping - size: 377639 - timestamp: 1753652392418 -- conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.10.1-py312h05f76fc_0.conda - sha256: 5fa98c506eec4013a6b5936f7c3d7391b0b3c946155ccdb25458c4b4ddcec89c - md5: 48c1bbcca918b91de7582a4d4fe71c1c - depends: - - python >=3.12,<3.13.0a0 - - python_abi 3.12.* *_cp312 - - tomli - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/coverage?source=hash-mapping - size: 402061 - timestamp: 1753652639361 -- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - sha256: ce61f4f99401a4bd455b89909153b40b9c823276aefcbb06f2044618696009ca - md5: 72e42d28960d875c7654614f8b50939a - depends: - - python >=3.9 - - typing_extensions >=4.6.0 - license: MIT and PSF-2.0 - purls: - - pkg:pypi/exceptiongroup?source=hash-mapping - size: 21284 - timestamp: 1746947398083 -- pypi: https://files.pythonhosted.org/packages/8a/6d/f596954df87cfa05b82a9f7f2bbda486b40465378c978998f06058eecdfa/gavicore-0.0.7-py3-none-any.whl - name: gavicore - version: 0.0.7 - sha256: a357a02d07607e60f11e64440282b08045c6b001aabdcb9dee1aba9460c4c23e - requires_dist: - - pydantic - - typer - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - sha256: 71e750d509f5fa3421087ba88ef9a7b9be11c53174af3aa4d06aff4c18b38e8e - md5: 8b189310083baabfb622af68fd9d3ae3 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 - license: MIT - license_family: MIT - purls: [] - size: 12129203 - timestamp: 1720853576813 -- conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda - sha256: 0ec8f4d02053cd03b0f3e63168316530949484f80e16f5e2fb199a1d117a89ca - md5: 6837f3eff7dcea42ecd714ce1ac2b108 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/iniconfig?source=hash-mapping - size: 11474 - timestamp: 1733223232820 -- conda: https://conda.anaconda.org/conda-forge/noarch/isort-6.0.1-pyhd8ed1ab_1.conda - sha256: e1d0e81e3c3da5d7854f9f57ffb89d8f4505bb64a2f05bb01d78eff24344a105 - md5: c25d1a27b791dab1797832aafd6a3e9a - depends: - - python >=3.9,<4.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/isort?source=hash-mapping - size: 75118 - timestamp: 1746190379093 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1423503_1.conda - sha256: 1a620f27d79217c1295049ba214c2f80372062fd251b569e9873d4a953d27554 - md5: 0be7c6e070c19105f966d3758448d018 - depends: - - __glibc >=2.17,<3.0.a0 - constrains: - - binutils_impl_linux-64 2.44 - license: GPL-3.0-only - license_family: GPL - purls: [] - size: 676044 - timestamp: 1752032747103 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda - sha256: da2080da8f0288b95dd86765c801c6e166c4619b910b11f9a8446fb852438dc2 - md5: 4211416ecba1866fab0c6470986c22d6 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - constrains: - - expat 2.7.1.* - license: MIT - license_family: MIT - purls: [] - size: 74811 - timestamp: 1752719572741 -- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.1-hac47afa_0.conda - sha256: 8432ca842bdf8073ccecf016ccc9140c41c7114dc4ec77ca754551c01f780845 - md5: 3608ffde260281fa641e70d6e34b1b96 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - expat 2.7.1.* - license: MIT - license_family: MIT - purls: [] - size: 141322 - timestamp: 1752719767870 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - sha256: 764432d32db45466e87f10621db5b74363a9f847d2b8b1f9743746cd160f06ab - md5: ede4673863426c0883c0063d853bbd85 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: MIT - license_family: MIT - purls: [] - size: 57433 - timestamp: 1743434498161 -- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda - sha256: d3b0b8812eab553d3464bbd68204f007f1ebadf96ce30eb0cbc5159f72e353f5 - md5: 85d8fa5e55ed8f93f874b3b23ed54ec6 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT - purls: [] - size: 44978 - timestamp: 1743435053850 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_3.conda - sha256: 59a87161212abe8acc57d318b0cc8636eb834cdfdfddcf1f588b5493644b39a3 - md5: 9e60c55e725c20d23125a5f0dd69af5d - depends: - - __glibc >=2.17,<3.0.a0 - - _openmp_mutex >=4.5 - constrains: - - libgcc-ng ==15.1.0=*_3 - - libgomp 15.1.0 h767d61c_3 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 824921 - timestamp: 1750808216066 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_3.conda - sha256: b0b0a5ee6ce645a09578fc1cb70c180723346f8a45fdb6d23b3520591c6d6996 - md5: e66f2b8ad787e7beb0f846e4bd7e8493 - depends: - - libgcc 15.1.0 h767d61c_3 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 29033 - timestamp: 1750808224854 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_3.conda - sha256: 43710ab4de0cd7ff8467abff8d11e7bb0e36569df04ce1c099d48601818f11d1 - md5: 3cd1a7238a0dd3d0860fdefc496cc854 - depends: - - __glibc >=2.17,<3.0.a0 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 447068 - timestamp: 1750808138400 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 - md5: 1a580f7796c7bf6393fddb8bbbde58dc - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - constrains: - - xz 5.8.1.* - license: 0BSD - purls: [] - size: 112894 - timestamp: 1749230047870 -- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda - sha256: 55764956eb9179b98de7cc0e55696f2eff8f7b83fc3ebff5e696ca358bca28cc - md5: c15148b2e18da456f5108ccb5e411446 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - constrains: - - xz 5.8.1.* - license: 0BSD - purls: [] - size: 104935 - timestamp: 1749230611612 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - sha256: 927fe72b054277cde6cb82597d0fcf6baf127dcbce2e0a9d8925a68f1265eef5 - md5: d864d34357c3b65a4b731f78c0801dc4 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: LGPL-2.1-only - license_family: GPL - purls: [] - size: 33731 - timestamp: 1750274110928 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.3-hee844dc_1.conda - sha256: 8c4faf560815a6d6b5edadc019f76d22a45171eaa707a1f1d1898ceda74b2e3f - md5: 18d2ac95b507ada9ca159a6bd73255f7 - depends: - - __glibc >=2.17,<3.0.a0 - - icu >=75.1,<76.0a0 - - libgcc >=14 - - libzlib >=1.3.1,<2.0a0 - license: blessing - purls: [] - size: 936339 - timestamp: 1753262589168 -- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.50.4-hf5d6505_0.conda - sha256: 5dc4f07b2d6270ac0c874caec53c6984caaaa84bc0d3eb593b0edf3dc8492efa - md5: ccb20d946040f86f0c05b644d5eadeca - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: blessing - purls: [] - size: 1288499 - timestamp: 1753948889360 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_3.conda - sha256: 7650837344b7850b62fdba02155da0b159cf472b9ab59eb7b472f7bd01dff241 - md5: 6d11a5edae89fe413c0569f16d308f5a - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc 15.1.0 h767d61c_3 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 3896407 - timestamp: 1750808251302 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_3.conda - sha256: bbaea1ecf973a7836f92b8ebecc94d3c758414f4de39d2cc6818a3d10cb3216b - md5: 57541755b5a51691955012b8e197c06c - depends: - - libstdcxx 15.1.0 h8f9b012_3 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 29093 - timestamp: 1750808292700 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - sha256: 787eb542f055a2b3de553614b25f09eefb0a0931b0c87dbcce6efdfd92f04f18 - md5: 40b61aab5c7ba9ff276c41cfffe6b80b - depends: - - libgcc-ng >=12 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 33601 - timestamp: 1680112270483 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c - md5: 5aa797f8787fe7a17d1b0821485b5adc - depends: - - libgcc-ng >=12 - license: LGPL-2.1-or-later - purls: [] - size: 100393 - timestamp: 1702724383534 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 - md5: edb0dca6bc32e4f4789199455a1dbeb8 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - constrains: - - zlib 1.3.1 *_2 - license: Zlib - license_family: Other - purls: [] - size: 60963 - timestamp: 1727963148474 -- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - sha256: ba945c6493449bed0e6e29883c4943817f7c79cbff52b83360f7b341277c6402 - md5: 41fbfac52c601159df6c01f875de31b9 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - constrains: - - zlib 1.3.1 *_2 - license: Zlib - license_family: Other - purls: [] - size: 55476 - timestamp: 1727963768015 -- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - sha256: 0fbacdfb31e55964152b24d5567e9a9996e1e7902fb08eb7d91b5fd6ce60803a - md5: fee3164ac23dfca50cfcc8b85ddefb81 - depends: - - mdurl >=0.1,<1 - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/markdown-it-py?source=hash-mapping - size: 64430 - timestamp: 1733250550053 -- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - sha256: 78c1bbe1723449c52b7a9df1af2ee5f005209f67e40b6e1d3c7619127c43b1c7 - md5: 592132998493b3ff25fd7479396e8351 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/mdurl?source=hash-mapping - size: 14465 - timestamp: 1733255681319 -- conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.17.0-py312h4c3975b_0.conda - sha256: f7a427cc6e94fc3c5be83ff0b48509a9a41e9ab48065a14101d0d13b2dd7c9bf - md5: ebf26f1cfb032d55a2f433ea7a3139f7 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - mypy_extensions >=1.0.0 - - pathspec >=0.9.0 - - psutil >=4.0 - - python >=3.12,<3.13.0a0 - - python_abi 3.12.* *_cp312 - - typing_extensions >=4.6.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/mypy?source=hash-mapping - size: 18931157 - timestamp: 1752534887158 -- conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.17.1-py312he06e257_0.conda - sha256: cf163c187fa4a53fb9213c2a2da0db70adfd5432132b71323919fb9e915d1c5b - md5: 2350dfef1eb807972168872c1fed8b8b - depends: - - mypy_extensions >=1.0.0 - - pathspec >=0.9.0 - - psutil >=4.0 - - python >=3.12,<3.13.0a0 - - python_abi 3.12.* *_cp312 - - typing_extensions >=4.6.0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: - - pkg:pypi/mypy?source=hash-mapping - size: 10122280 - timestamp: 1754002942945 -- conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - sha256: 6ed158e4e5dd8f6a10ad9e525631e35cee8557718f83de7a4e3966b1f772c4b1 - md5: e9c622e0d00fa24a6292279af3ab6d06 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/mypy-extensions?source=hash-mapping - size: 11766 - timestamp: 1745776666688 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 - md5: 47e340acb35de30501a76c7c799c41d7 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: X11 AND BSD-3-Clause - purls: [] - size: 891641 - timestamp: 1738195959188 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.1-h7b32b05_0.conda - sha256: 942347492164190559e995930adcdf84e2fea05307ec8012c02a505f5be87462 - md5: c87df2ab1448ba69169652ab9547082d - depends: - - __glibc >=2.17,<3.0.a0 - - ca-certificates - - libgcc >=13 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 3131002 - timestamp: 1751390382076 -- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.5.1-h725018a_0.conda - sha256: 2b2eb73b0661ff1aed55576a3d38614852b5d857c2fa9205ac115820c523306c - md5: d124fc2fd7070177b5e2450627f8fc1a - depends: - - ca-certificates - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 9327033 - timestamp: 1751392489008 -- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - sha256: 289861ed0c13a15d7bbb408796af4de72c2fe67e2bcb0de98f4c3fce259d7991 - md5: 58335b26c38bf4a20f399384c33cbcf9 - depends: - - python >=3.8 - - python - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/packaging?source=hash-mapping - size: 62477 - timestamp: 1745345660407 -- conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - sha256: 9f64009cdf5b8e529995f18e03665b03f5d07c0b17445b8badef45bde76249ee - md5: 617f15191456cc6a13db418a275435e5 - depends: - - python >=3.9 - license: MPL-2.0 - license_family: MOZILLA - purls: - - pkg:pypi/pathspec?source=hash-mapping - size: 41075 - timestamp: 1733233471940 -- conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda - sha256: a8eb555eef5063bbb7ba06a379fa7ea714f57d9741fe0efdb9442dbbc2cccbcc - md5: 7da7ccd349dbf6487a7778579d2bb971 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pluggy?source=hash-mapping - size: 24246 - timestamp: 1747339794916 -- pypi: https://files.pythonhosted.org/packages/35/53/f31ab23c29a5a25084948774ee4a43d02d8b1076e8498de9152afda62768/procodile-0.0.7-py3-none-any.whl - name: procodile - version: 0.0.7 - sha256: 7e50cf0f94cec1e1e796ddf18b49c2b2c3b8464f919472a96090f37abca86106 - requires_dist: - - gavicore>=0.0.7 - - pydantic - - pyyaml - - typer - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.0.0-py312h66e93f0_0.conda - sha256: 158047d7a80e588c846437566d0df64cec5b0284c7184ceb4f3c540271406888 - md5: 8e30db4239508a538e4a3b3cdf5b9616 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - python >=3.12,<3.13.0a0 - - python_abi 3.12.* *_cp312 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 466219 - timestamp: 1740663246825 -- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.0.0-py312h4389bb4_0.conda - sha256: 088451ee2c9a349e1168f70afe275e58f86350faffb09c032cff76f97d4fb7bb - md5: f5b86d6e2e645ee276febe79a310b640 - depends: - - python >=3.12,<3.13.0a0 - - python_abi 3.12.* *_cp312 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 484682 - timestamp: 1740663813103 -- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - sha256: ee7823e8bc227f804307169870905ce062531d36c1dcf3d431acd65c6e0bd674 - md5: 1b337e3d378cde62889bb735c024b7a2 - depends: - - annotated-types >=0.6.0 - - pydantic-core 2.33.2 - - python >=3.9 - - typing-extensions >=4.6.1 - - typing-inspection >=0.4.0 - - typing_extensions >=4.12.2 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pydantic?source=hash-mapping - size: 307333 - timestamp: 1749927245525 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.33.2-py312h680f630_0.conda - sha256: 4d14d7634c8f351ff1e63d733f6bb15cba9a0ec77e468b0de9102014a4ddc103 - md5: cfbd96e5a0182dfb4110fc42dda63e57 - depends: - - python - - typing-extensions >=4.6.0,!=4.7.0 - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - python_abi 3.12.* *_cp312 - constrains: - - __glibc >=2.17 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pydantic-core?source=hash-mapping - size: 1890081 - timestamp: 1746625309715 -- conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.33.2-py312h8422cdd_0.conda - sha256: f377214abd06f1870011a6068b10c9e23dc62065d4c2de13b2f0a6014636e0ae - md5: c61e3f191da309117e0b0478b49f6e91 - depends: - - python - - typing-extensions >=4.6.0,!=4.7.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - ucrt >=10.0.20348.0 - - python_abi 3.12.* *_cp312 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pydantic-core?source=hash-mapping - size: 1900306 - timestamp: 1746625389678 -- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a - md5: 6b6ece66ebcae2d5f326c77ef2c5a066 - depends: - - python >=3.9 - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/pygments?source=hash-mapping - size: 889287 - timestamp: 1750615908735 -- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.1-pyhd8ed1ab_0.conda - sha256: 93e267e4ec35353e81df707938a6527d5eb55c97bf54c3b87229b69523afb59d - md5: a49c2283f24696a7b30367b7346a0144 - depends: - - colorama >=0.4 - - exceptiongroup >=1 - - iniconfig >=1 - - packaging >=20 - - pluggy >=1.5,<2 - - pygments >=2.7.2 - - python >=3.9 - - tomli >=1 - constrains: - - pytest-faulthandler >=2 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pytest?source=hash-mapping - size: 276562 - timestamp: 1750239526127 -- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.2.1-pyhd8ed1ab_0.conda - sha256: 3a9fc07be76bc67aef355b78816b5117bfe686e7d8c6f28b45a1f89afe104761 - md5: ce978e1b9ed8b8d49164e90a5cdc94cd - depends: - - coverage >=7.5 - - pytest >=4.6 - - python >=3.9 - - toml - license: MIT - license_family: MIT - purls: - - pkg:pypi/pytest-cov?source=hash-mapping - size: 28216 - timestamp: 1749778064293 -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.11-h9e4cc4f_0_cpython.conda - sha256: 6cca004806ceceea9585d4d655059e951152fc774a471593d4f5138e6a54c81d - md5: 94206474a5608243a10c92cefbe0908f - depends: - - __glibc >=2.17,<3.0.a0 - - bzip2 >=1.0.8,<2.0a0 - - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.7.0,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 - - libgcc >=13 - - liblzma >=5.8.1,<6.0a0 - - libnsl >=2.0.1,<2.1.0a0 - - libsqlite >=3.50.0,<4.0a0 - - libuuid >=2.38.1,<3.0a0 - - libxcrypt >=4.4.36 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.0,<4.0a0 - - readline >=8.2,<9.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - constrains: - - python_abi 3.12.* *_cp312 - license: Python-2.0 - purls: [] - size: 31445023 - timestamp: 1749050216615 -- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.12.11-h3f84c4b_0_cpython.conda - sha256: b69412e64971b5da3ced0fc36f05d0eacc9393f2084c6f92b8f28ee068d83e2e - md5: 6aa5e62df29efa6319542ae5025f4376 - depends: - - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.0,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 - - liblzma >=5.8.1,<6.0a0 - - libsqlite >=3.50.0,<4.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - constrains: - - python_abi 3.12.* *_cp312 - license: Python-2.0 - purls: [] - size: 15829289 - timestamp: 1749047682640 -- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-8_cp312.conda - build_number: 8 - sha256: 80677180dd3c22deb7426ca89d6203f1c7f1f256f2d5a94dc210f6e758229809 - md5: c3efd25ac4d74b1584d2f7a57195ddf1 - constrains: - - python 3.12.* *_cpython - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 6958 - timestamp: 1752805918820 -- pypi: https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl - name: pyyaml - version: 6.0.3 - sha256: 5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: pyyaml - version: 6.0.3 - sha256: ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - sha256: 2d6d0c026902561ed77cd646b5021aef2d4db22e57a5b0178dfc669231e06d2c - md5: 283b96675859b20a825f8fa30f311446 - depends: - - libgcc >=13 - - ncurses >=6.5,<7.0a0 - license: GPL-3.0-only - license_family: GPL - purls: [] - size: 282480 - timestamp: 1740379431762 -- conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.1.0-pyhe01879c_0.conda - sha256: 3bda3cd6aa2ca8f266aeb8db1ec63683b4a7252d7832e8ec95788fb176d0e434 - md5: c41e49bd1f1479bed6c6300038c5466e - depends: - - markdown-it-py >=2.2.0 - - pygments >=2.13.0,<3.0.0 - - python >=3.9 - - typing_extensions >=4.0.0,<5.0.0 - - python - license: MIT - purls: - - pkg:pypi/rich?source=hash-mapping - size: 201098 - timestamp: 1753436991345 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.12.5-hf9daec2_0.conda - noarch: python - sha256: e0383ea982545b0836771b58cd6d5e516f722d02b899f5bf325a54c8f6ef73b4 - md5: 37a142ca01da7f87652d55a1fb5043e8 - depends: - - python - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - constrains: - - __glibc >=2.17 - license: MIT - purls: - - pkg:pypi/ruff?source=hash-mapping - size: 10477480 - timestamp: 1753401049977 -- conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.12.7-hd40eec1_0.conda - noarch: python - sha256: b20947e8ec4f4fdb0b13045e16b97ebf4747c6f65b38107615239a924fdfb5d4 - md5: 82a88723dba120f3b7070e68523a1c9a - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/ruff?source=hash-mapping - size: 10858681 - timestamp: 1753906142349 -- pypi: ./ - name: s2gos-app-ex - version: 0.0.0 - sha256: fe053f016670ef03d9da693a3bfc9b912ad8dcb5dfe429ca625ffd59a768cc7d - requires_python: '>=3.10' - editable: true -- conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_1.conda - sha256: 0557c090913aa63cdbe821dbdfa038a321b488e22bc80196c4b3b1aace4914ef - md5: 7c3c2a0f3ebdea2bbc35538d162b43bf - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/shellingham?source=hash-mapping - size: 14462 - timestamp: 1733301007770 -- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda - sha256: a84ff687119e6d8752346d1d408d5cf360dee0badd487a472aa8ddedfdc219e1 - md5: a0116df4f4ed05c303811a837d5b39d8 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libzlib >=1.3.1,<2.0a0 - license: TCL - license_family: BSD - purls: [] - size: 3285204 - timestamp: 1748387766691 -- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda - sha256: e3614b0eb4abcc70d98eae159db59d9b4059ed743ef402081151a948dce95896 - md5: ebd0e761de9aa879a51d22cc721bd095 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: TCL - license_family: BSD - purls: [] - size: 3466348 - timestamp: 1748388121356 -- conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda - sha256: 34f3a83384ac3ac30aefd1309e69498d8a4aa0bf2d1f21c645f79b180e378938 - md5: b0dd904de08b7db706167240bf37b164 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/toml?source=hash-mapping - size: 22132 - timestamp: 1734091907682 -- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhe01879c_2.conda - sha256: 040a5a05c487647c089ad5e05ad5aff5942830db2a4e656f1e300d73436436f1 - md5: 30a0a26c8abccf4b7991d590fe17c699 - depends: - - python >=3.9 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/tomli?source=compressed-mapping - size: 21238 - timestamp: 1753796677376 -- conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.16.0-pyh167b9f4_0.conda - sha256: 1ca70f0c0188598f9425a947afb74914a068bee4b7c4586eabb1c3b02fbf669f - md5: 985cc086b73bda52b2f8d66dcda460a1 - depends: - - typer-slim-standard ==0.16.0 hf964461_0 - - python >=3.9 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/typer?source=hash-mapping - size: 77232 - timestamp: 1748304246569 -- conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.16.0-pyhe01879c_0.conda - sha256: 54f859ddf5d3216fb602f54990c3ccefc65a30d1d98c400b998e520310630df3 - md5: 0d0a6c08daccb968c8c8fa93070658e2 - depends: - - python >=3.9 - - click >=8.0.0 - - typing_extensions >=3.7.4.3 - - python - constrains: - - typer 0.16.0.* - - rich >=10.11.0 - - shellingham >=1.3.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/typer-slim?source=hash-mapping - size: 46798 - timestamp: 1748304246569 -- conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.16.0-hf964461_0.conda - sha256: c35a0b232e9751ac871b733d4236eee887f64c3b1539ba86aecf175c3ac3dc02 - md5: c8fb6ddb4f5eb567d049f85b3f0c8019 - depends: - - typer-slim ==0.16.0 pyhe01879c_0 - - rich - - shellingham - license: MIT - license_family: MIT - purls: [] - size: 5271 - timestamp: 1748304246569 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.14.1-h4440ef1_0.conda - sha256: 349951278fa8d0860ec6b61fcdc1e6f604e6fce74fabf73af2e39a37979d0223 - md5: 75be1a943e0a7f99fcf118309092c635 - depends: - - typing_extensions ==4.14.1 pyhe01879c_0 - license: PSF-2.0 - license_family: PSF - purls: [] - size: 90486 - timestamp: 1751643513473 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.1-pyhd8ed1ab_0.conda - sha256: 4259a7502aea516c762ca8f3b8291b0d4114e094bdb3baae3171ccc0900e722f - md5: e0c3cd765dc15751ee2f0b03cd015712 - depends: - - python >=3.9 - - typing_extensions >=4.12.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/typing-inspection?source=hash-mapping - size: 18809 - timestamp: 1747870776989 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.1-pyhe01879c_0.conda - sha256: 4f52390e331ea8b9019b87effaebc4f80c6466d09f68453f52d5cdc2a3e1194f - md5: e523f4f1e980ed7a4240d7e27e9ec81f - depends: - - python >=3.9 - - python - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/typing-extensions?source=hash-mapping - size: 51065 - timestamp: 1751643513473 -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - sha256: 5aaa366385d716557e365f0a4e9c3fca43ba196872abbbe3d56bb610d131e192 - md5: 4222072737ccff51314b5ece9c7d6f5a - license: LicenseRef-Public-Domain - purls: [] - size: 122968 - timestamp: 1742727099393 -- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - sha256: db8dead3dd30fb1a032737554ce91e2819b43496a0db09927edf01c32b577450 - md5: 6797b005cd0f439c4c5c9ac565783700 - constrains: - - vs2015_runtime >=14.29.30037 - license: LicenseRef-MicrosoftWindowsSDK10 - purls: [] - size: 559710 - timestamp: 1728377334097 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_31.conda - sha256: cb357591d069a1e6cb74199a8a43a7e3611f72a6caed9faa49dbb3d7a0a98e0b - md5: 28f4ca1e0337d0f27afb8602663c5723 - depends: - - vc14_runtime >=14.44.35208 - track_features: - - vc14 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 18249 - timestamp: 1753739241465 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_31.conda - sha256: af4b4b354b87a9a8d05b8064ff1ea0b47083274f7c30b4eb96bc2312c9b5f08f - md5: 603e41da40a765fd47995faa021da946 - depends: - - ucrt >=10.0.20348.0 - - vcomp14 14.44.35208 h818238b_31 - constrains: - - vs2015_runtime 14.44.35208.* *_31 - license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime - license_family: Proprietary - purls: [] - size: 682424 - timestamp: 1753739239305 -- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_31.conda - sha256: 67b317b64f47635415776718d25170a9a6f9a1218c0f5a6202bfd687e07b6ea4 - md5: a6b1d5c1fc3cb89f88f7179ee6a9afe3 - depends: - - ucrt >=10.0.20348.0 - constrains: - - vs2015_runtime 14.44.35208.* *_31 - license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime - license_family: Proprietary - purls: [] - size: 113963 - timestamp: 1753739198723 diff --git a/s2gos-app-ex/pyproject.toml b/s2gos-app-ex/pyproject.toml deleted file mode 100644 index b4e3e87..0000000 --- a/s2gos-app-ex/pyproject.toml +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -[project] -name = "s2gos-app-ex" -version = "0.0.0" -description = "Application example for the ESA DTE-S2GOS synthetic scene generator service" -readme = "README.md" -authors = [ - {name = "Norman Fomferra (Brockmann Consult GmbH)"}, - {name = "Tejas Morbagal Harish (Brockmann Consult GmbH)"} -] -keywords = [ - "synthetic scene generation", - "esa", - "eRadiate", - "zarr" -] -license = {text = "Apache-2.0"} -classifiers = [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Science/Research", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Topic :: Software Development", - "Topic :: Scientific/Engineering", - "Typing :: Typed", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Operating System :: Unix", - "Operating System :: MacOS", -] -requires-python = ">=3.10" - -[project.scripts] -s2gos-app-ex = "s2gos_app_ex.cli:cli" - -[tool.pixi.project] -channels = ["conda-forge"] -platforms = ["linux-64", "win-64"] - -[tool.pixi.dependencies] -python = "3.12.*" -typer = ">=0.16.0,<0.17" -pydantic = ">=2.11.7,<3" - -[tool.pixi.pypi-dependencies] -procodile = ">=0.0.7" -s2gos-app-ex = { path = ".", editable = true } - -[tool.pixi.feature.dev.dependencies] -pytest = "*" -pytest-cov = "*" -ruff = "*" -isort = "*" -mypy = "*" - -[tool.pixi.environments] -production = { solve-group = "prod" } -default = { features = ["dev"], solve-group = "prod" } - -[tool.isort] -skip = [".idea", ".github", ".pixi", "htmlcov", "site"] -profile = "black" -line_length = 88 -known_first_party = ["s2gos_app_ex"] - -[build-system] -requires = ["hatch"] -build-backend = "hatchling.build" - -[tool.hatch.build] -sources = ["src"] - -[tool.hatch.build.targets.sdist] -include = [ - "src/s2gos_app_ex/**/*", - "pyproject.toml", - "README.md", - "LICENSE", -] - -[tool.hatch.build.targets.wheel] -include = [ - "src/s2gos_app_ex/**/*" -] diff --git a/s2gos-app-ex/src/s2gos_app_ex/cli.py b/s2gos-app-ex/src/s2gos_app_ex/cli.py deleted file mode 100644 index 13b134b..0000000 --- a/s2gos-app-ex/src/s2gos_app_ex/cli.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from procodile.cli import get_cli - -# The CLI with a basic set of commands. -# The `cli` is a Typer application of type `typer.Typer()`, -# so can use the instance to register your own commands. -cli = get_cli("s2gos_app_ex.processes:registry") - - -__all__ = ["cli"] diff --git a/s2gos-app-ex/src/s2gos_app_ex/processes.py b/s2gos-app-ex/src/s2gos_app_ex/processes.py deleted file mode 100644 index e63a9d3..0000000 --- a/s2gos-app-ex/src/s2gos_app_ex/processes.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Annotated - -from pydantic import Field - -from procodile import JobContext, ProcessRegistry - -registry = ProcessRegistry() - - -@registry.process( - id="sleep_a_while", - title="Sleepy Process", -) -def sleep_a_while( - duration: Annotated[float, Field(title="Duration in s", gt=0)] = 10.0, - fail: Annotated[bool, Field(title="Force failure")] = False, -) -> float: - """ - Sleeps for `duration` seconds. - Fails on purpose if `fail` is `True` after 50% progress. - Returns the effective amount of sleep in seconds. - """ - import time - - ctx = JobContext.get() - - t0 = time.time() - for i in range(101): - ctx.report_progress(progress=i) - if fail and i == 50: - raise RuntimeError("Woke up too early") - time.sleep(duration / 100) - return time.time() - t0 - - -@registry.process( - id="primes_between", - title="Prime Generator", -) -def primes_between( - ctx: JobContext, - min_val: Annotated[int, Field(title="Minimum value of search range", ge=0)] = 0, - max_val: Annotated[int, Field(title="Maximum value of search range", ge=0)] = 100, -) -> list[int]: - """Computes the list of prime numbers within an integer value range.""" - - if max_val < 2 or max_val <= min_val: - raise ValueError("max_val must be greater 1 and greater min_val") - - ctx.report_progress(message="Step 1: Generate sieve up to sqrt(max_val)") - limit = int(max_val**0.5) + 1 - is_prime_small = [True] * (limit + 1) - is_prime_small[0:2] = [False, False] - for i in range(2, int(limit**0.5) + 1): - if is_prime_small[i]: - for j in range(i * i, limit + 1, i): - is_prime_small[j] = False - small_primes = [i for i, prime in enumerate(is_prime_small) if prime] - - ctx.report_progress( - message="Step 2: Create the sieve for the range [min_val, max_val]" - ) - sieve_range = max_val - min_val + 1 - is_prime = [True] * sieve_range - - for p in small_primes: - # Find the first multiple of p in the range [min_val, max_val] - start = max(p * p, ((min_val + p - 1) // p) * p) - for j in range(start, max_val + 1, p): - is_prime[j - min_val] = False - - for n in range(min_val, min(min_val + 2, max_val + 1)): - if n < 2: - is_prime[n - min_val] = False - - ctx.report_progress(message="Done") - return [min_val + i for i, prime in enumerate(is_prime) if prime] diff --git a/s2gos-client/pyproject.toml b/s2gos-client/pyproject.toml index 8bd3bc7..cf7f26e 100644 --- a/s2gos-client/pyproject.toml +++ b/s2gos-client/pyproject.toml @@ -38,15 +38,9 @@ classifiers = [ ] requires-python = ">=3.10" dependencies = [ - "click", - "pydantic", - "pyyaml", - "typer", - "uri-template", - "httpx", # Eozilla dependencies - "cuiman", - "gavicore", + "cuiman >=0.0.8", + "gavicore >=0.0.8", ] [project.scripts] diff --git a/s2gos-client/src/s2gos_client/__init__.py b/s2gos-client/src/s2gos_client/__init__.py index 6d179ca..38b3c01 100644 --- a/s2gos-client/src/s2gos_client/__init__.py +++ b/s2gos-client/src/s2gos_client/__init__.py @@ -15,3 +15,8 @@ "ClientError", "__version__", ] + +# TODO: set final S2GOS gateway server URL +DEFAULT_SERVER_URL = "http://127.0.0.1:8008" + +ClientConfig.set_default(ClientConfig(server_url=DEFAULT_SERVER_URL)) diff --git a/s2gos-client/src/s2gos_client/cli.py b/s2gos-client/src/s2gos_client/cli.py index ab7d70f..003fc4e 100644 --- a/s2gos-client/src/s2gos_client/cli.py +++ b/s2gos-client/src/s2gos_client/cli.py @@ -2,14 +2,14 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -from cuiman.cli import get_cli +from cuiman.cli import new_cli -from s2gos_server import __version__ as version +from s2gos_client import __version__ as version -cli = get_cli( - "s2gos-client", - summary="Interact with the ESA DTE S2GOS service.", +cli = new_cli( + name="s2gos-client", version=version, + summary="Interact with the ESA DTE S2GOS processing service.", ) __all__ = [ diff --git a/s2gos-app-ex/src/s2gos_app_ex/__init__.py b/s2gos-client/tests/__init__.py similarity index 100% rename from s2gos-app-ex/src/s2gos_app_ex/__init__.py rename to s2gos-client/tests/__init__.py diff --git a/s2gos-common/src/s2gos_common/py.typed b/s2gos-client/tests/py.typed similarity index 100% rename from s2gos-common/src/s2gos_common/py.typed rename to s2gos-client/tests/py.typed diff --git a/s2gos-client/src/tests/test_api.py b/s2gos-client/tests/test_api.py similarity index 100% rename from s2gos-client/src/tests/test_api.py rename to s2gos-client/tests/test_api.py diff --git a/s2gos-client/src/tests/test_cli.py b/s2gos-client/tests/test_cli.py similarity index 100% rename from s2gos-client/src/tests/test_cli.py rename to s2gos-client/tests/test_cli.py diff --git a/s2gos-client/src/tests/test_gui.py b/s2gos-client/tests/test_gui.py similarity index 100% rename from s2gos-client/src/tests/test_gui.py rename to s2gos-client/tests/test_gui.py diff --git a/s2gos-common/LICENSE b/s2gos-common/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/s2gos-common/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/s2gos-common/README.md b/s2gos-common/README.md deleted file mode 100644 index 3fce2b8..0000000 --- a/s2gos-common/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# DTE-S2GOS controller data models - -Python data models for the ESA DTE-S2GOS synthetic scene generator service - diff --git a/s2gos-common/pyproject.toml b/s2gos-common/pyproject.toml deleted file mode 100644 index 7a69166..0000000 --- a/s2gos-common/pyproject.toml +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -[project] -name = "s2gos-common" -version = "0.0.6.dev0" -description = "Python data models for the ESA DTE-S2GOS synthetic scene generator service" -readme = "README.md" -authors = [ - {name = "Norman Fomferra (Brockmann Consult GmbH)"}, - {name = "Tejas Morbagal Harish (Brockmann Consult GmbH)"} -] -keywords = [ - "synthetic scene generation", - "esa", - "eRadiate", - "zarr" -] -license = {text = "Apache-2.0"} -classifiers = [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Science/Research", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Topic :: Software Development", - "Topic :: Scientific/Engineering", - "Typing :: Typed", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Operating System :: Unix", - "Operating System :: MacOS", -] -requires-python = ">=3.10" -dependencies = [ - "pydantic", - "typer", -] - -[project.urls] -Documentation = "https://s2gos-dev.github.io/s2gos-controller" -Repository = "https://github.com/s2gos-dev/s2gos-controller" -Changelog = "https://github.com/s2gos-dev/s2gos-controller/blob/main/CHANGES.md" -Issues = "https://github.com/s2gos-dev/s2gos-controller/issues" - -[build-system] -requires = ["hatch"] -build-backend = "hatchling.build" - -[tool.hatch.build] -sources = ["src"] -exclude = ["src/tests/**/*"] - -[tool.hatch.build.targets.sdist] -include = [ - "src/s2gos_common/**/*", - "pyproject.toml", - "README.md", - "LICENSE", -] - -[tool.hatch.build.targets.wheel] -include = [ - "src/s2gos_common/**/*" -] diff --git a/s2gos-common/src/s2gos_common/__init__.py b/s2gos-common/src/s2gos_common/__init__.py deleted file mode 100644 index 08fe27c..0000000 --- a/s2gos-common/src/s2gos_common/__init__.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - - -import inspect -from importlib.metadata import version - -from pydantic import BaseModel - -from . import models, service - -__version__ = version("s2gos-common") - -__all__ = [ - "__version__", - "models", - "service", -] - - -def _patch_models(): - for name, obj in inspect.getmembers(models, inspect.isclass): - if ( - not name.startswith("_") - and obj.__module__ == models.__name__ - and issubclass(obj, BaseModel) - ): - # Make model object render nicely in Jupyter notebooks - setattr(obj, "_repr_json_", _repr_base_model_as_json) - - -def _repr_base_model_as_json(self: BaseModel): - return self.model_dump( - mode="json", by_alias=True, exclude_none=True, exclude_defaults=True - ), dict(root=self.__class__.__name__ + " object:") - - -_patch_models() diff --git a/s2gos-common/src/s2gos_common/models.py b/s2gos-common/src/s2gos_common/models.py deleted file mode 100644 index 08d9f03..0000000 --- a/s2gos-common/src/s2gos_common/models.py +++ /dev/null @@ -1,315 +0,0 @@ -# generated by datamodel-codegen: -# filename: openapi.yaml -# timestamp: 2025-10-08T12:50:40+00:00 - -from __future__ import annotations - -from datetime import date -from enum import Enum -from typing import Annotated, Any, Optional, Union - -from pydantic import AnyUrl, AwareDatetime, BaseModel, ConfigDict, Field, RootModel - - -class CRS(Enum): - http___www_opengis_net_def_crs_OGC_1_3_CRS84 = ( - "http://www.opengis.net/def/crs/OGC/1.3/CRS84" - ) - http___www_opengis_net_def_crs_OGC_0_CRS84h = ( - "http://www.opengis.net/def/crs/OGC/0/CRS84h" - ) - - -class ApiError(BaseModel): - """ - API error based on RFC 7807 - """ - - model_config = ConfigDict( - extra="allow", - ) - type: str - title: Optional[str] = None - status: Optional[int] = None - detail: Optional[str] = None - instance: Optional[str] = None - traceback: Optional[list[str]] = None - - -class MaxOccurs(Enum): - unbounded = "unbounded" - - -class Link(BaseModel): - href: str - rel: Optional[str] = Field(None, examples=["service"]) - type: Optional[str] = Field(None, examples=["application/json"]) - hreflang: Optional[str] = Field(None, examples=["en"]) - title: Optional[str] = None - - -class Bbox(BaseModel): - bbox: list[float] = Field(..., max_length=4, min_length=4) - crs: Optional[CRS] = CRS.http___www_opengis_net_def_crs_OGC_1_3_CRS84 - - -class DataType(Enum): - array = "array" - boolean = "boolean" - integer = "integer" - number = "number" - object = "object" - string = "string" - - -class Metadata(BaseModel): - title: Optional[str] = None - role: Optional[str] = None - href: Optional[str] = None - - -class AdditionalParameter(BaseModel): - name: str - value: list[Union[str, float, int, list[dict[str, Any]], dict[str, Any]]] - - -class TransmissionMode(Enum): - value = "value" - reference = "reference" - - -class Capabilities(BaseModel): - title: Optional[str] = Field(None, examples=["Example processing server"]) - description: Optional[str] = Field( - None, - examples=["Example server implementing the OGC API - Processes 1.0 Standard"], - ) - links: list[Link] - - -class ConformanceDeclaration(BaseModel): - conformsTo: list[str] - - -class ResponseType(Enum): - raw = "raw" - document = "document" - - -class Subscriber(BaseModel): - """ - Optional URIs for callbacks for this job. - - Support for this parameter is not required and the parameter may be - removed from the API definition, if conformance class **'callback'** - is not listed in the conformance declaration under `/conformance`. - """ - - successUri: Optional[AnyUrl] = None - inProgressUri: Optional[AnyUrl] = None - failedUri: Optional[AnyUrl] = None - - -class JobStatus(Enum): - accepted = "accepted" - running = "running" - successful = "successful" - failed = "failed" - dismissed = "dismissed" - - -class JobType(Enum): - process = "process" - - -class JobControlOptions(Enum): - sync_execute = "sync-execute" - async_execute = "async-execute" - dismiss = "dismiss" - - -class JobInfo(BaseModel): - processID: Optional[str] = None - type: JobType - jobID: str - status: JobStatus - message: Optional[str] = None - created: Optional[AwareDatetime] = None - started: Optional[AwareDatetime] = None - finished: Optional[AwareDatetime] = None - updated: Optional[AwareDatetime] = None - progress: Annotated[Optional[int], Field(None, ge=0, le=100)] = None - links: Optional[list[Link]] = None - traceback: Optional[list[str]] = None - - -class InlineValue( - RootModel[ - Union[ - Any, - bool, - bytes, - AnyUrl, - date, - AwareDatetime, - str, - int, - float, - list, - dict[str, Any], - Bbox, - ] - ] -): - root: Union[ - Any, - bool, - bytes, - AnyUrl, - date, - AwareDatetime, - str, - int, - float, - list, - dict[str, Any], - Bbox, - ] - - -class AdditionalParameters(Metadata): - parameters: Optional[list[AdditionalParameter]] = None - - -class DescriptionType(BaseModel): - title: Optional[str] = None - description: Optional[str] = None - keywords: Optional[list[str]] = None - metadata: Optional[list[Metadata]] = None - additionalParameters: Optional[AdditionalParameters] = None - - -class ProcessSummary(DescriptionType): - id: str - version: str - jobControlOptions: Optional[list[JobControlOptions]] = None - outputTransmission: Optional[list[TransmissionMode]] = None - links: Optional[list[Link]] = None - - -class JobList(BaseModel): - jobs: list[JobInfo] - links: list[Link] - - -class ProcessList(BaseModel): - processes: list[ProcessSummary] - links: list[Link] - - -class Format(BaseModel): - mediaType: Optional[str] = None - encoding: Optional[str] = None - schema_: Optional[Union[AnyUrl, Schema]] = Field(None, alias="schema") - - -# TODO - Code has been manually moved here after class Format, -# because it was wrongly placed last by the datamodel-code-generator tool -# That's why we also use the tool with keep_model_order=False - which is by -# the way also a bug, as it does the opposite of what it should. -# See https://github.com/koxudaxi/datamodel-code-generator/issues/2508 -# PLEASE MAKE SURE YOU INCLUDE THIS COMMENT AS LONG AS THE PROBLEM PERSISTS. -class QualifiedValue(Format): - value: InlineValue - - -class InlineOrRefValue(RootModel[Union[InlineValue, QualifiedValue, Link]]): - root: Union[InlineValue, QualifiedValue, Link] - - -class Discriminator(BaseModel): - propertyName: Optional[str] = Field(None, min_length=1) - mapping: Optional[dict[str, Schema]] = None - - -class Schema(BaseModel): - model_config = ConfigDict( - extra="forbid", - ) - field_ref: Optional[str] = Field(None, alias="$ref") - title: Optional[str] = None - multipleOf: Optional[float] = Field(None, gt=0.0) - maximum: Optional[float] = None - exclusiveMaximum: Optional[bool] = False - minimum: Optional[float] = None - exclusiveMinimum: Optional[bool] = False - maxLength: Optional[int] = Field(None, ge=0) - minLength: Optional[int] = Field(0, ge=0) - pattern: Optional[str] = None - maxItems: Optional[int] = Field(None, ge=0) - minItems: Optional[int] = Field(0, ge=0) - uniqueItems: Optional[bool] = False - maxProperties: Optional[int] = Field(None, ge=0) - minProperties: Optional[int] = Field(0, ge=0) - required: Optional[list[str]] = Field(None, min_length=1) - enum: Optional[list] = Field(None, min_length=1) - type: Optional[DataType] = None - not_: Optional[Schema] = Field(None, alias="not") - allOf: Optional[list[Schema]] = None - oneOf: Optional[list[Schema]] = None - anyOf: Optional[list[Schema]] = None - discriminator: Optional[Discriminator] = None - items: Optional[Union[list[Schema], Schema]] = None - properties: Optional[dict[str, Schema]] = None - additionalProperties: Optional[Union[Schema, bool]] = True - description: Optional[str] = None - format: Optional[str] = None - default: Optional[Any] = None - nullable: Optional[bool] = False - readOnly: Optional[bool] = False - writeOnly: Optional[bool] = False - example: Optional[Any] = None - examples: Optional[Any] = None - deprecated: Optional[bool] = False - contentMediaType: Optional[str] = None - contentEncoding: Optional[str] = None - contentSchema: Optional[str] = None - - -class ProcessDescription(ProcessSummary): - inputs: Optional[dict[str, InputDescription]] = None - outputs: Optional[dict[str, OutputDescription]] = None - - -class ProcessRequest(BaseModel): - inputs: Optional[dict[str, Any]] = None - outputs: Optional[dict[str, Output]] = None - response: Optional[ResponseType] = ResponseType.raw - subscriber: Optional[Subscriber] = None - - -class InputDescription(DescriptionType): - minOccurs: Optional[int] = 1 - maxOccurs: Optional[Union[int, MaxOccurs]] = None - schema_: Schema = Field(..., alias="schema") - - -class OutputDescription(DescriptionType): - schema_: Schema = Field(..., alias="schema") - - -class Output(BaseModel): - format: Optional[Format] = None - transmissionMode: Optional[TransmissionMode] = TransmissionMode.value - - -class JobResults(RootModel[Optional[dict[str, InlineOrRefValue]]]): - root: Optional[dict[str, InlineOrRefValue]] = None - - -Format.model_rebuild() -InlineOrRefValue.model_rebuild() -Discriminator.model_rebuild() -ProcessDescription.model_rebuild() -ProcessRequest.model_rebuild() -QualifiedValue.model_rebuild() diff --git a/s2gos-common/src/s2gos_common/process/__init__.py b/s2gos-common/src/s2gos_common/process/__init__.py deleted file mode 100644 index 076b429..0000000 --- a/s2gos-common/src/s2gos_common/process/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from .cli.cli import get_cli -from .job import Job, JobCancelledException, JobContext -from .process import Process -from .registry import ProcessRegistry -from .request import ExecutionRequest - -"""Processes development API.""" - -__all__ = [ - "ExecutionRequest", - "Job", - "JobContext", - "JobCancelledException", - "ProcessRegistry", - "Process", - "get_cli", -] diff --git a/s2gos-common/src/s2gos_common/process/cli/__init__.py b/s2gos-common/src/s2gos_common/process/cli/__init__.py deleted file mode 100644 index 060b158..0000000 --- a/s2gos-common/src/s2gos_common/process/cli/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -# No exports here. To avoid unnecessary imports, CLI apps should pick -# only what they need from dedicated submodules. diff --git a/s2gos-common/src/s2gos_common/process/cli/cli.py b/s2gos-common/src/s2gos_common/process/cli/cli.py deleted file mode 100644 index 09a3b1c..0000000 --- a/s2gos-common/src/s2gos_common/process/cli/cli.py +++ /dev/null @@ -1,202 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import json -from typing import TYPE_CHECKING, Annotated, Callable, Optional, Union - -import click -import typer - -from s2gos_common.util.cli.group import AliasedGroup -from s2gos_common.util.cli.parameters import ( - DOT_PATH_OPTION, - PROCESS_ID_ARGUMENT, - REQUEST_FILE_OPTION, - REQUEST_INPUT_OPTION, - REQUEST_SUBSCRIBER_OPTION, -) - -if TYPE_CHECKING: # pragma: no cover - from s2gos_common.process import ProcessRegistry - - -PROCESS_REGISTRY_GETTER_KEY = "get_process_registry" - -CLI_HELP = """Command-line interface for process description and execution. - -You can use shorter command name aliases, e.g., use command name `ep` -for `execute-process`, or `lp` for `list-processes`. -""" - -cli = typer.Typer( - add_completion=False, - cls=AliasedGroup, - help=CLI_HELP, - context_settings={ - "obj": {PROCESS_REGISTRY_GETTER_KEY: None}, - }, -) - - -def get_cli( - process_registry: Union[str, "ProcessRegistry", Callable[[], "ProcessRegistry"]], - **kwargs, -) -> typer.Typer: - """ - Get the CLI instance configured to use the process registry - that is given either by - - - a reference of the form "path.to.module:attribute", - - or process registry instance, - - or as a no-arg process registry getter function. - - The process registry is usually a singleton in your application. - - The context object `obj` of the returned CLI object - will be of type `dict` and will contain - a process registry getter function using the key - `get_process_registry`. - - The function must be called before any CLI command or - callback has been invoked. Otherwise, the provided - `get_process_registry` getter will not be recognized and - all commands that require the process registry will - fail with an `AssertionError`. - - Args: - process_registry: A registry reference string, - or a registry instance, or a no-arg - function that returns a registry instance. - kwargs: Additional context values that will be registered in the - - """ - if isinstance(process_registry, str): - - def get_process_registry(): - from s2gos_common.process import ProcessRegistry - from s2gos_common.util.dynimp import import_value - - return import_value( - process_registry, name="process registry", type=ProcessRegistry - ) - - return get_cli(get_process_registry) - - elif not callable(process_registry): - return get_cli(lambda: process_registry) - - assert callable(process_registry) - context_settings = cli.info.context_settings - assert isinstance(context_settings, dict) - context_obj = context_settings["obj"] - assert isinstance(context_obj, dict) - context_obj.update({PROCESS_REGISTRY_GETTER_KEY: process_registry, **kwargs}) - return cli - - -__all__ = [ - "get_cli", -] - - -@cli.command("execute-process") -def execute_process( - ctx: typer.Context, - process_id: Annotated[Optional[str], PROCESS_ID_ARGUMENT] = None, - dotpath: Annotated[bool, DOT_PATH_OPTION] = False, - request_inputs: Annotated[Optional[list[str]], REQUEST_INPUT_OPTION] = None, - request_subscribers: Annotated[ - Optional[list[str]], REQUEST_SUBSCRIBER_OPTION - ] = None, - request_file: Annotated[Optional[str], REQUEST_FILE_OPTION] = None, -): - """ - Execute a process. - - The process request to be submitted may be read from a file given - by `--request`, or from `stdin`, or from the `process_id` argument - with zero, one, or more `--input` (or `-i`) options. - - The `process_id` argument and any given `--input` options will override - settings with same name found in the given request file or `stdin`, if any. - """ - from s2gos_common.process import Job - from s2gos_common.process.request import ExecutionRequest - - process_registry = _get_process_registry(ctx) - execution_request = ExecutionRequest.create( - process_id=process_id, - dotpath=dotpath, - inputs=request_inputs, - subscribers=request_subscribers, - request_path=request_file, - ) - process_id_ = execution_request.process_id - process = process_registry.get(process_id_) - if process is None: - raise click.ClickException(f"Process {process_id_!r} not found.") - - job = Job.create(process, request=execution_request.to_process_request()) - job_results = job.run() - if job_results is not None: - typer.echo(job_results.model_dump_json(indent=2)) - else: - typer.echo(job.job_info.model_dump_json(indent=2)) - - -@cli.command("list-processes", help="List all processes.") -def list_processes(ctx: typer.Context): - process_registry = _get_process_registry(ctx) - typer.echo( - json.dumps( - { - k: v.description.model_dump( - mode="json", - by_alias=True, - exclude_none=True, - exclude_defaults=True, - exclude_unset=True, - exclude={"inputs", "outputs"}, - ) - for k, v in process_registry.items() - }, - indent=2, - ) - ) - - -@cli.command("get-process", help="Get details of a process.") -def get_process( - ctx: typer.Context, - process_id: Annotated[str, PROCESS_ID_ARGUMENT], -): - import json - - process_registry = _get_process_registry(ctx) - process = process_registry.get(process_id) - if process is None: - raise click.ClickException(f"Process {process_id!r} not found.") - - typer.echo( - json.dumps( - process.description.model_dump( - mode="json", - by_alias=True, - exclude_defaults=True, - exclude_none=True, - exclude_unset=True, - ), - indent=2, - ) - ) - - -def _get_process_registry(ctx: typer.Context) -> "ProcessRegistry": - from s2gos_common.process import ProcessRegistry - - process_registry_getter = ctx.obj.get(PROCESS_REGISTRY_GETTER_KEY) - assert process_registry_getter is not None and callable(process_registry_getter) - process_registry = process_registry_getter() - assert isinstance(process_registry, ProcessRegistry) - return process_registry diff --git a/s2gos-common/src/s2gos_common/process/job.py b/s2gos-common/src/s2gos_common/process/job.py deleted file mode 100644 index ca922fa..0000000 --- a/s2gos-common/src/s2gos_common/process/job.py +++ /dev/null @@ -1,348 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import datetime -import inspect -import traceback -import uuid -import warnings -from abc import ABC, abstractmethod -from concurrent.futures import Future -from typing import Any, Optional - -import pydantic - -from s2gos_common.models import ( - JobInfo, - JobResults, - JobStatus, - JobType, - ProcessRequest, - Schema, - Subscriber, -) - -from .process import Process -from .reporter import CallbackReporter - - -class JobCancelledException(Exception): - """Raised if a job's cancellation has been requested.""" - - -class JobContext(ABC): - """ - Report process progress and check for task cancellation. - - A process function can retrieve the current job context - - 1. via [JobContext.get()][s2gos_common.process.JobContext.get] from - within a process function, or - 2. as a function argument of type [JobContext][s2gos_common.process.JobContext]. - """ - - @classmethod - def get(cls) -> "JobContext": - """ - Get the current job context. - - Returns the current job context that can be used by - process functions to report job progress in percent - or via messages and to check whether cancellation - has been requested. - This function is intended to be called from within - a process function executed as a job. If called as a usual - Python function (without a job serving as context), the - returned context will have no-op methods only. - - Returns: - An instance of the current job context. - """ - frame = inspect.currentframe() - try: - while frame: - job_context = frame.f_locals.get("__job_context__") - if isinstance(job_context, JobContext): - return job_context - frame = frame.f_back - finally: - # Always free alive frame-references - del frame - # noinspection PyUnreachableCode - warnings.warn( - "cannot determine current job context; using non-functional dummy" - ) - return NullJobContext() - - @abstractmethod - def report_progress( - self, - progress: Optional[int] = None, - message: Optional[str] = None, - ) -> None: - """Report task progress. - - Args: - progress: Progress in percent. - message: Detail progress message. - - Raises: - JobCancellationException: if an attempt has been made - to cancel this job. - """ - - @abstractmethod - def is_cancelled(self) -> bool: - """Test whether an attempt has been made to cancel this job. - It may still be running though. - - Returns: - `True` if so, `False` otherwise. - """ - - @abstractmethod - def check_cancelled(self) -> None: - """Raise a `JobCancellationException`, if - an attempt has been made to cancel this job. - """ - - -class Job(JobContext): - """ - Represents an execution of a user function. - - Args: - process: The process that created this job. - job_id: A job identifier. - function_kwargs: The user function's keyword arguments. - A keyword must be a valid Python identifier or a - sequence of Python identifiers separated by the dot - (`.`) character. - subscriber: Optional subscriber URIs. - """ - - @classmethod - def create( - cls, - process: Process, - request: ProcessRequest, - job_id: Optional[str] = None, - ) -> "Job": - """ - Create a new job for the given process and process request. - - Args: - process: The process. - request: The process request. - Names of request inputs must be valid Python identifiers or - sequences of Python identifiers separated by the dot - (`.`) character. The latter is used to set nested input objects. - job_id: Optional job identifier. - If omitted, a unique identifier will be generated (UUID4). - - Returns: - A new job instance. - - Raises: - pydantic.ValidationError: if an input value is not valid - with respect to its process input description. - """ - process_desc = process.description - input_params = request.inputs or {} - input_default_params = { - input_name: input_info.schema_.default - for input_name, input_info in (process_desc.inputs or {}).items() - if isinstance(input_info.schema_, Schema) - and input_info.schema_.default is not None - } - input_values: dict[str, Any] = {} - for input_name in (process_desc.inputs or {}).keys(): - if input_name in input_params: - input_values[input_name] = input_params[input_name] - elif input_name in input_default_params: - input_values[input_name] = input_default_params[input_name] - - model_instance: pydantic.BaseModel = process.model_class(**input_values) - - function_kwargs = { - k: getattr(model_instance, k) - for k in process.model_class.model_fields.keys() - if k in input_values - } - - return Job( - process=process, - job_id=job_id or f"{uuid.uuid4()}", - function_kwargs=function_kwargs, - subscriber=request.subscriber, - ) - - def __init__( - self, - *, - process: Process, - job_id: str, - function_kwargs: dict[str, Any], - subscriber: Optional[Subscriber] = None, - ): - """Internal constructor. - Use `Job.create() instead.` - """ - self.process = process - # noinspection PyTypeChecker - self.job_info = JobInfo( # noqa [call-arg] - type=JobType.process, - processID=process.description.id, - jobID=job_id, - status=JobStatus.accepted, - created=self._now(), - ) - self.function_kwargs = function_kwargs - self.cancelled = False - self.future: Optional[Future] = None - self.subscriber = subscriber - self._reporter: CallbackReporter | None = None - - @property - def reporter(self) -> CallbackReporter: - if self._reporter is None: - self._reporter = CallbackReporter() - return self._reporter - - def report_progress( - self, progress: Optional[int] = None, message: Optional[str] = None - ): - self.check_cancelled() - # noinspection PyTypeChecker - self.job_info.updated = self._now() - if progress is not None: - self.job_info.progress = progress - if message is not None: - self.job_info.message = message - self._maybe_notify_in_progress() - - def is_cancelled(self) -> bool: - return self.cancelled - - def check_cancelled(self): - if self.cancelled: - raise JobCancelledException - - def cancel(self): - """Request job cancellation. - Note, actual cancellation will happen - only from within the user function. - """ - self.cancelled = True - - def run(self) -> JobResults | None: - """Run this job.""" - - # Make the job (context) findable by get_job_context() - # through the local variable __job_context__ - ctx = __job_context__ = self # noqa: F841 - - function_kwargs: dict[str, Any] = dict(self.function_kwargs) - - # use "inputs arg", if needed - inputs_arg = self.process.inputs_arg - if inputs_arg: - function_kwargs.pop(inputs_arg, None) - function_kwargs = {inputs_arg: self.process.model_class(**function_kwargs)} - - # inject job context, if needed - ctx_arg = self.process.job_ctx_arg - if ctx_arg: - function_kwargs.pop(ctx_arg, None) - function_kwargs = {ctx_arg: ctx, **function_kwargs} - - self._start_job() - try: - self.check_cancelled() - function_result = self.process.function(**function_kwargs) - self._finish_job(JobStatus.successful) - job_results = self._get_job_results(function_result) - self._maybe_notify_success(job_results) - return job_results - except JobCancelledException: - self._finish_job(JobStatus.dismissed) - self._maybe_notify_failed() - except Exception as e: - self._finish_job(JobStatus.failed, exception=e) - self._maybe_notify_failed() - return None - - def _get_job_results(self, function_result: Any) -> JobResults: - assert self.job_info.status == JobStatus.successful - assert self.job_info.processID is not None - outputs = self.process.description.outputs or {} - output_count = len(outputs) - return JobResults( - **{ - output_name: ( - function_result if output_count == 1 else function_result[i] - ) - for i, output_name in enumerate(outputs.keys()) - } - ) - - def _start_job(self): - # noinspection PyTypeChecker - self.job_info.started = self._now() - self.job_info.status = JobStatus.running - - def _finish_job(self, job_status: JobStatus, exception: Optional[Exception] = None): - # noinspection PyTypeChecker - self.job_info.finished = self._now() - self.job_info.status = job_status - if exception is not None: - self.job_info.message = f"{exception}" - self.job_info.traceback = traceback.format_exception( - type(exception), exception, exception.__traceback__ - ) - - def _maybe_notify_success(self, job_results: JobResults): - if self.subscriber is not None and self.subscriber.successUri is not None: - url = str(self.subscriber.successUri) - data = job_results.model_dump(mode="json", by_alias=True) - self.reporter.report(url, data) - - def _maybe_notify_failed(self): - if self.subscriber is not None: - self._maybe_notify_current_job_info(self.subscriber.failedUri) - - def _maybe_notify_in_progress(self): - if self.subscriber is not None: - self._maybe_notify_current_job_info(self.subscriber.inProgressUri) - - def _maybe_notify_current_job_info(self, url: pydantic.AnyUrl | None): - if url is not None: - data = self.job_info.model_dump( - mode="json", - by_alias=True, - exclude_none=True, - exclude_unset=True, - ) - self.reporter.report(str(url), data) - - @staticmethod - def _now() -> datetime.datetime: - # noinspection PyTypeChecker - return datetime.datetime.now(tz=datetime.timezone.utc) - - -class NullJobContext(JobContext): - """A job context used if a real one could not be provided.""" - - def report_progress( - self, progress: Optional[int] = None, message: Optional[str] = None - ) -> None: - """Does nothing.""" - - def is_cancelled(self) -> bool: - """Returns `False`.""" - return False - - def check_cancelled(self) -> None: - """Does nothing.""" diff --git a/s2gos-common/src/s2gos_common/process/process.py b/s2gos-common/src/s2gos_common/process/process.py deleted file mode 100644 index f50b9ab..0000000 --- a/s2gos-common/src/s2gos_common/process/process.py +++ /dev/null @@ -1,268 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import inspect -from dataclasses import dataclass -from typing import Any, Callable, Literal, Optional, get_args, get_origin - -import pydantic - -from s2gos_common.models import ( - InputDescription, - OutputDescription, - ProcessDescription, -) - -from .schema import create_json_schema, create_schema_instance - - -@dataclass -class Process: - """ - A process comprises a process description and executable code - in form of a Python function. - - Instances of this class are be managed by the - [ProcessRegistry][s2gos_common.process.ProcessRegistry]. - - Attributes: - function: The user's Python function. - signature: The signature of `function`. - job_ctx_arg: Names of `function` arguments of type `JobContext`. - model_class: Pydantic model class for the arguments of `function`. - description: Process description modelled after - [OGC API - Processes - Part 1: Core](https://docs.ogc.org/is/18-062r2/18-062r2.html#toc37). - """ - - function: Callable - signature: inspect.Signature - model_class: type[pydantic.BaseModel] - description: ProcessDescription - # names of special arguments - inputs_arg: str | None - job_ctx_arg: str | None - - # noinspection PyShadowingBuiltins - @classmethod - def create( - cls, - function: Callable, - id: Optional[str] = None, - version: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - input_fields: Optional[dict[str, pydantic.fields.FieldInfo]] = None, - output_fields: Optional[dict[str, pydantic.fields.FieldInfo]] = None, - inputs_arg: str | bool = False, - ) -> "Process": - """Create a new instance of this dataclass. - - Called by the `ProcessRegistry.process()` decorator function. - Not intended to be used by clients. - """ - if not inspect.isfunction(function): - raise TypeError("function argument must be callable") - fn_name = f"{function.__module__}:{function.__qualname__}" - id = id or fn_name - version = version or "0.0.0" - description = description or inspect.getdoc(function) - signature = inspect.signature(function) - inputs, model_class, input_arg_, job_ctx_arg = _parse_inputs( - fn_name, signature, input_fields, inputs_arg - ) - outputs = _parse_outputs(fn_name, signature.return_annotation, output_fields) - return Process( - function=function, - signature=signature, - model_class=model_class, - description=ProcessDescription( - id=id, - version=version, - title=title, - description=description, - inputs=inputs, - outputs=outputs, - # Note, we may later add the following: - # metadata=metadata, - # keywords=keywords, - # links=links, - # outputTransmission=output_transmission, - # jobControlOptions=job_control_options, - ), - inputs_arg=input_arg_, - job_ctx_arg=job_ctx_arg, - ) - - -def _parse_inputs( - fn_name: str, - signature: inspect.Signature, - input_fields: Optional[dict[str, pydantic.fields.FieldInfo]] | None, - inputs_arg: str | bool, -) -> tuple[ - dict[str, InputDescription], type[pydantic.BaseModel], str | None, str | None -]: - arg_parameters, job_ctx_arg = _parse_parameters(fn_name, signature) - - model_class: type[pydantic.BaseModel] - input_arg_: str | None = None - if inputs_arg: - model_class, input_arg_ = _parse_input_arg(fn_name, arg_parameters, inputs_arg) - else: - model_field_definitions: dict[str, Any] = { - param_name: ( - (parameter.annotation, parameter.default) - if parameter.default is not inspect.Parameter.empty - else parameter.annotation - ) - for param_name, parameter in arg_parameters.items() - } - model_class = pydantic.create_model("ProcessInputs", **model_field_definitions) - - if input_fields: - model_class = _merge_input_fields_into_model_class( - fn_name, signature, input_fields, model_class - ) - - model_class.model_rebuild() - - inputs_schema = create_json_schema(model_class) - input_descriptions = { - input_name: InputDescription( - minOccurs=1 if input_name in inputs_schema.get("required", []) else 0, - maxOccurs=None, - title=schema.pop("title", None), - description=schema.pop("description", None), - schema=create_schema_instance(input_name, schema), - ) - for input_name, schema in inputs_schema.get("properties", {}).items() - } - - return input_descriptions, model_class, input_arg_, job_ctx_arg - - -def _parse_parameters( - fn_name: str, signature: inspect.Signature -) -> tuple[dict[str, inspect.Parameter], str | None]: - from .job import JobContext - - arg_parameters: dict[str, inspect.Parameter] = {} - job_ctx_arg: str | None = None - for param_name, parameter in signature.parameters.items(): - if parameter.annotation is JobContext: - if job_ctx_arg: - raise ValueError( - f"function {fn_name!r}: only one parameter can have type " - f"{JobContext.__name__}, but found {job_ctx_arg!r} " - f"and {param_name!r}" - ) - job_ctx_arg = param_name - else: - arg_parameters[param_name] = parameter - return arg_parameters, job_ctx_arg - - -def _merge_input_fields_into_model_class( - fn_name: str, - signature: inspect.Signature, - input_fields: dict[str, pydantic.fields.FieldInfo], - model_class: type[pydantic.BaseModel], -) -> type[pydantic.BaseModel]: - invalid_inputs = [ - input_name - for input_name in input_fields - if input_name not in signature.parameters - ] - if invalid_inputs: - raise ValueError( - f"function {fn_name!r}: " - "all input names must have corresponding parameter names; " - f"invalid input name(s): {', '.join(map(repr, invalid_inputs))}" - ) - - # noinspection PyTypeChecker - model_field_definitions: dict[str, Any] = dict(model_class.model_fields) - for input_name, field_info in input_fields.items(): - if input_name in model_field_definitions: - old_field_info = model_field_definitions[input_name] - parameter = signature.parameters[input_name] - model_field_definitions[input_name] = ( - parameter.annotation, - pydantic.fields.FieldInfo.merge_field_infos(old_field_info, field_info), - ) - - return pydantic.create_model(model_class.__name__, **model_field_definitions) - - -def _parse_input_arg( - fn_name: str, - arg_parameters: dict[str, inspect.Parameter], - inputs_arg: str | Literal[True], -) -> tuple[type[pydantic.BaseModel], str]: - if len(arg_parameters) > 1: - raise ValueError( - f"function {fn_name!r}: the inputs argument must be the only " - f"argument (inputs_arg={inputs_arg!r})" - ) - - inputs_arg_param: inspect.Parameter | None - if isinstance(inputs_arg, str): - inputs_arg_param = arg_parameters.get(inputs_arg) - else: - inputs_arg_param = ( - list(arg_parameters.values())[0] if len(arg_parameters) == 1 else None - ) - - if inputs_arg_param is None: - raise ValueError( - f"function {fn_name!r}: specified inputs argument " - f"is not an argument of the function (inputs_arg={inputs_arg!r})" - ) - - model_class = inputs_arg_param.annotation - # noinspection PyTypeChecker - if isinstance(model_class, type) and issubclass(model_class, pydantic.BaseModel): - return model_class, inputs_arg_param.name - else: - raise TypeError( - f"function {fn_name!r}: type of inputs argument " - f"{inputs_arg_param.name!r} must be a subclass of pydantic.BaseModel" - ) - - -def _parse_outputs( - fn_name: str, - annotation: type, - output_fields: Optional[dict[str, pydantic.fields.FieldInfo]] | None, -) -> dict[str, OutputDescription]: - model_field_definitions: dict[str, Any] = {} - if not output_fields: - model_field_definitions = {"return_value": annotation} - elif len(output_fields) == 1: - output_name, field_info = next(iter(output_fields.items())) - model_field_definitions = {output_name: (annotation, field_info)} - else: - origin = get_origin(annotation) - args = get_args(annotation) - if not (origin is tuple and args): - raise TypeError( - f"function {fn_name!r}: return type must be tuple[] with arguments" - ) - if len(args) != len(output_fields): - raise ValueError( - f"function {fn_name!r}: number of outputs must match number " - f"of tuple[] arguments" - ) - for arg_type, (output_name, field_info) in zip(args, output_fields.items()): - model_field_definitions[output_name] = (arg_type, field_info) - model_class = pydantic.create_model("Outputs", **model_field_definitions) - outputs_schema = create_json_schema(model_class) - output_descriptions = {} - for output_name, schema in outputs_schema.get("properties", {}).items(): - output_descriptions[output_name] = OutputDescription( - title=schema.pop("title", None), - description=schema.pop("description", None), - schema=create_schema_instance(output_name, schema), - ) - return output_descriptions diff --git a/s2gos-common/src/s2gos_common/process/registry.py b/s2gos-common/src/s2gos_common/process/registry.py deleted file mode 100644 index b37f9f6..0000000 --- a/s2gos-common/src/s2gos_common/process/registry.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from collections.abc import Iterator, Mapping -from typing import Callable, Optional - -import pydantic - -from .process import Process - - -class ProcessRegistry(Mapping[str, Process]): - """ - A registry for processes. - - Processes are Python functions with extra metadata. - - Represents a read-only mapping from process identifiers to - [Process][s2gos_common.process.Process] instances. - """ - - def __init__(self): - self._processes: dict[str, Process] = {} - - def __getitem__(self, process_id: str, /) -> Process: - return self._processes[process_id] - - def __len__(self) -> int: - return len(self._processes) - - def __iter__(self) -> Iterator[str]: - return iter(self._processes) - - # noinspection PyShadowingBuiltins - def process( - self, - function: Optional[Callable] = None, - /, - *, - id: Optional[str] = None, - version: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - input_fields: Optional[dict[str, pydantic.fields.FieldInfo]] = None, - output_fields: Optional[dict[str, pydantic.fields.FieldInfo]] = None, - inputs_arg: str | bool = False, - ) -> Callable[[Callable], Callable] | Callable: - """ - A decorator that can be applied to a user function in order to - register it as a process in this registry. - - The decorator can be used with or without parameters. - - Args: - function: The decorated function that is passed automatically since - `process()` is a decorator function. - id: Optional process identifier. Must be unique within the registry. - If not provided, the fully qualified function name will be used. - version: Optional version identifier. If not provided, `"0.0.0"` - will be used. - title: Optional, short process title. - description: Optional, detailed description of the process. If not - provided, the function's docstring, if any, will be used. - input_fields: Optional mapping from function argument names - to [`pydantic.Field`](https://docs.pydantic.dev/latest/concepts/fields/) - annotations. The preferred way is to annotate the arguments directly - as described in [The Annotated Pattern](https://docs.pydantic.dev/latest/concepts/fields/#the-annotated-pattern). - output_fields: Mapping from output names to - [`pydantic.Field`](https://docs.pydantic.dev/latest/concepts/fields/) - annotations. Required, if you have multiple outputs returned as a - dictionary. In this case, output names are the keys of your returned - dictionary. - inputs_arg: Specifies the use of an _inputs argument_. An inputs argument - is a container for the actual process inputs. If specified, it must - be the only function argument (besides an optional job context - argument) and must be a subclass of `pydantic.BaseModel`. - If `inputs_arg` is `True` the only argument will be the input argument, - if `inputs_arg` is a `str` it must be the name of the only argument. - """ - - def register_process(fn: Callable): - process = Process.create( - fn, - id=id, - version=version, - title=title, - description=description, - input_fields=input_fields, - output_fields=output_fields, - inputs_arg=inputs_arg, - ) - self._processes[process.description.id] = process - return fn - - if function is not None: - return register_process(function) - else: - return register_process diff --git a/s2gos-common/src/s2gos_common/process/reporter.py b/s2gos-common/src/s2gos_common/process/reporter.py deleted file mode 100644 index 1c7c30d..0000000 --- a/s2gos-common/src/s2gos_common/process/reporter.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import json -import logging -import threading -from typing import Any -from urllib import error, request - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - -_Payload = tuple[str, dict[str, Any]] - - -class CallbackReporter: - def __init__( - self, - request_timeout: float = 1.0, - check_interval: float = 0.5, - ): - self.request_timeout = request_timeout - self.check_interval = check_interval - self._latest_payload: _Payload | None = None - self._lock = threading.Lock() - self._stop_event = threading.Event() - self._notify_event = threading.Event() - self._thread = threading.Thread(target=self._run, daemon=True) - self._thread.start() - - def report(self, url: str, data: dict[str, Any]): - with self._lock: - self._latest_payload = url, data - self._notify_event.set() - - def stop(self): - self._stop_event.set() - self._thread.join(timeout=2.0) - - def _run(self): - while not self._stop_event.is_set(): - triggered = self._notify_event.wait(timeout=self.check_interval) - if triggered: - self._notify_event.clear() - with self._lock: - payload = self._latest_payload - if payload: - try: - self._post_json(payload) - logger.info(f"Successfully posted status to {payload[0]}") - except (error.URLError, error.HTTPError) as e: - logger.warning("Post failed: %s", e) - except Exception as e: - logger.exception("Unexpected error in reporter: %s", e) - - def _post_json(self, payload: tuple[str, dict]): - url, data = payload - json_text = json.dumps(data).encode("utf-8") - req = request.Request( - url, - data=json_text, - headers={"Content-Type": "application/json"}, - method="POST", - ) - with request.urlopen(req, timeout=self.request_timeout) as resp: - resp.read() diff --git a/s2gos-common/src/s2gos_common/process/request.py b/s2gos-common/src/s2gos_common/process/request.py deleted file mode 100644 index f5e6b04..0000000 --- a/s2gos-common/src/s2gos_common/process/request.py +++ /dev/null @@ -1,256 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import sys -from io import StringIO -from pathlib import Path -from typing import Annotated, Any - -import click -import pydantic -from pydantic import Field - -from s2gos_common.models import ProcessDescription, ProcessRequest -from s2gos_common.util.obj import flatten_obj, nest_dict - -SUBSCRIBER_EVENTS = { - "success": "successUri", - "failed": "failedUri", - "progress": "inProgressUri", -} - - -# noinspection PyShadowingBuiltins -class ExecutionRequest(ProcessRequest): - """ - Process execution request. - Extends [ProcessRequest][ProcessRequest] - - - to allow the process identifier being part of the request, - - to allow creating nested object values for input names with dots. - - Args: - process_id: Process identifier - dotpath: Whether dots in input names should be used to create - nested object values. Defaults to `False`. - inputs: Optional process inputs given as key-value mapping. - Values may be of any JSON-serializable type accepted by - the given process. - outputs: Optional process outputs given as key-value mapping. - Values are of type [Output][s2gos_common.models.Output] - supported by the given process. - subscriber: Optional subscriber of type - [Subscriber][s2gos_common.models.Subscriber] comprising callback - URLs that are informed about process status changes - while the processing takes place. - """ - - process_id: Annotated[str, Field(title="Process identifier", min_length=1)] - dotpath: Annotated[ - bool, Field(title="Whether to encode nested input values using dots ('.').") - ] = False - - def to_process_request(self) -> ProcessRequest: - """ - Convert this execution request into a process request as used by the - `execute-process` operation. - """ - inputs = self.inputs - if inputs and self.dotpath: - inputs = nest_dict(inputs) - return ProcessRequest( - inputs=inputs, - outputs=self.outputs, - response=self.response, - subscriber=self.subscriber, - ) - - @classmethod - def create( - cls, - process_id: str | None = None, - dotpath: bool = False, - request_path: str | None = None, - inputs: list[str] | None = None, - subscribers: list[str] | None = None, - ) -> "ExecutionRequest": - request_dict, _ = _read_execution_request(request_path) - if process_id: - request_dict["process_id"] = process_id - if dotpath: - request_dict["dotpath"] = dotpath - inputs_dict = _parse_inputs(inputs) - if inputs_dict: - request_dict["inputs"] = dict(request_dict.get("inputs") or {}) - request_dict["inputs"].update(inputs_dict) - subscriber_dict = _parse_subscribers(subscribers) - if subscriber_dict: - request_dict["subscriber"] = dict(request_dict.get("subscriber") or {}) - request_dict["subscriber"].update(subscriber_dict) - try: - return ExecutionRequest(**request_dict) - except pydantic.ValidationError as e: - raise click.ClickException(f"Execution request is invalid: {e}") - - @classmethod - def from_process_description( - cls, - process_description: ProcessDescription, - dotpath: bool = False, - ) -> "ExecutionRequest": - """ - Create an execution request from the given process description. - - Args: - process_description: The process description - dotpath: Whether to allow for dot-separated input - names for nested object values - - Returns: - The execution requests populated with default values. - """ - return _from_process_description(process_description, dotpath) - - -def _read_execution_request( - request_path: Path | str | None = None, -) -> tuple[dict[str, Any], str]: - if not request_path: - return {}, "" - - if request_path == "-": - request_path = "" - # content = "\n".join(line for line in sys.stdin).strip() - content = sys.stdin.read().strip() - file_format = "json" if content.startswith("{") else "yaml" - else: - path = Path(request_path) - content = path.read_text() - file_format = "json" if path.suffix in (".json", ".JSON") else "yaml" - - if file_format == "json": - import json - - request_dict = json.loads(content) - else: - import yaml - - request_dict = yaml.safe_load(StringIO(content)) - - if not isinstance(request_dict, dict): - raise click.ClickException( - f"Request must be an object, but was type {type(request_dict).__name__}" - ) - - return request_dict, str(request_path) - - -def _parse_inputs(inputs: list[str] | None) -> dict[str, Any]: - return dict(_parse_inputs_kv(kv) for kv in (inputs or [])) - - -def _parse_inputs_kv(kv: str) -> tuple[str, str]: - parts = kv.split("=", maxsplit=1) - key, value = parts if len(parts) == 2 else (parts[0], "true") - return _parse_input_name(key), _parse_input_value(value) - - -def _parse_input_name(key: str) -> str: - norm_key = key.strip().replace("-", "_") - - property_names = key.split(".") - for property_name in property_names: - if not property_name.isidentifier(): - raise click.ClickException(f"Invalid request NAME: {key!r}") - - return norm_key - - -def _parse_input_value(value: str) -> Any: - import json - - try: - return json.loads(value) - except json.JSONDecodeError: - return value - - -def _parse_subscribers(subscribers: list[str] | None) -> dict[str, str]: - return dict(_parse_subscriber_kv(kv) for kv in (subscribers or [])) - - -def _parse_subscriber_kv(kv: str) -> tuple[str, str]: - try: - key, value = kv.split("=", maxsplit=1) - except ValueError: - raise click.ClickException( - f"Invalid subscriber item: must have form `EVENT=URL`, but was {kv!r}" - ) - return _parse_subscriber_event(key), _parse_subscriber_url(value) - - -def _parse_subscriber_event(key: str): - norm_key = SUBSCRIBER_EVENTS.get(key) - if norm_key is None: - raise click.ClickException( - "Invalid subscriber EVENT: must be one of " - f"[{'|'.join(SUBSCRIBER_EVENTS.keys())}], but was {key!r}" - ) - return norm_key - - -def _parse_subscriber_url(value: str): - from urllib.parse import urlparse - - url = urlparse(value) - if not all([url.scheme in ("http", "https"), url.netloc]): - raise click.ClickException(f"Invalid subscriber URL: {value!r}") - return value - - -# noinspection PyShadowingBuiltins -def _from_process_description( - process_description: ProcessDescription, dotpath: bool -) -> ExecutionRequest: - inputs = { - k: _get_schema_default_value( - v.schema_.model_dump(mode="json", exclude_unset=True) if v.schema_ else None - ) - for k, v in (process_description.inputs or {}).items() - } - if dotpath: - inputs = flatten_obj(inputs) - return ExecutionRequest( - process_id=process_description.id, dotpath=dotpath, inputs=inputs - ) - - -def _get_schema_default_value(schema: Any) -> Any: - if schema and isinstance(schema, dict): - if "default" in schema: - return schema["default"] - if "enum" in schema and isinstance(schema["enum"], list) and schema["enum"]: - return schema["enum"][0] - if "type" in schema and isinstance(schema["type"], str) and schema["type"]: - type_ = schema["type"] - if type_ == "object" and "properties" in schema: - properties_ = schema["properties"] - if properties_ and isinstance(properties_, dict): - return { - p_name: _get_schema_default_value(p_schema) - for p_name, p_schema in properties_.items() - } - return _JSON_DATA_TYPE_DEFAULT_VALUES.get(type_) - return None - - -_JSON_DATA_TYPE_DEFAULT_VALUES: dict[str, Any] = { - "null": None, - "boolean": False, - "integer": 0, - "number": 0, - "string": "", - "array": [], - "object": {}, -} diff --git a/s2gos-common/src/s2gos_common/process/schema.py b/s2gos-common/src/s2gos_common/process/schema.py deleted file mode 100644 index 5f351eb..0000000 --- a/s2gos-common/src/s2gos_common/process/schema.py +++ /dev/null @@ -1,108 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import copy -import json -from typing import Any - -import pydantic - -from s2gos_common.models import Schema - - -def create_schema_instance(name: str, schema: dict[str, Any]) -> Schema: - try: - return Schema(**schema) - except pydantic.ValidationError: - print(80 * ">") - print("name:", name) - print("schema:", json.dumps(schema, indent=2)) - print(80 * "<") - raise - - -def create_json_schema( - model_class: type[pydantic.BaseModel], -) -> dict[str, Any]: - model_class.model_rebuild() - schema = model_class.model_json_schema() - schema = inline_schema_refs(schema) - return backport_schema_to_openapi_3_0(schema) - - -def inline_schema_refs(schema: dict[str, Any]) -> dict[str, Any]: - defs: dict[str, Any] | None = schema.get("$defs") - if not defs: - return schema - schema = copy.copy(schema) - schema.pop("$defs") - return _inline_schema_refs(schema, {f"#/$defs/{k}": v for k, v in defs.items()}) - - -def _inline_schema_refs(schema: dict[str, Any], defs: dict[str, Any]) -> dict[str, Any]: - if "$ref" in schema: - ref = schema["$ref"] - if ref in defs: - ref_schema = _inline_schema_refs(defs[ref], defs) - schema = copy.copy(schema) - schema.pop("$ref") - schema.update(copy.deepcopy(ref_schema)) - return schema - schema = copy.copy(schema) - for k in ("allOf", "anyOf", "oneOf"): - if k in schema: - if isinstance(schema[k], list): - schema[k] = [_inline_schema_refs(s, defs) for s in schema[k]] - for k in ("items", "prefixItems", "additionalProperties"): - if k in schema: - if isinstance(schema[k], list): - schema[k] = [_inline_schema_refs(s, defs) for s in schema[k]] - else: - schema[k] = _inline_schema_refs(schema[k], defs) - for k in ("properties",): - if k in schema: - if isinstance(schema[k], dict): - schema[k] = { - k: _inline_schema_refs(s, defs) for k, s in schema[k].items() - } - return schema - - -def backport_schema_to_openapi_3_0(schema: dict[str, Any]) -> dict[str, Any]: - if "type" in schema: - type_ = schema["type"] - if type_ == "null": - schema.pop("type") - schema["nullable"] = True - if "prefixItems" in schema: - prefix_items = schema.pop("prefixItems") - if prefix_items: - # Care, this is a naive implementation: - schema["items"] = backport_schema_to_openapi_3_0(prefix_items[0]) - for schema_key in ("items", "additionalProperties"): - if schema_key in schema: - if isinstance(schema[schema_key], (list, tuple)): - schema[schema_key] = list( - map(backport_schema_to_openapi_3_0, schema[schema_key]) - ) - elif isinstance(schema[schema_key], dict): - schema[schema_key] = backport_schema_to_openapi_3_0(schema[schema_key]) - for dict_key in ("properties", "$defs"): - if dict_key in schema and isinstance(schema[dict_key], dict): - schema[dict_key] = { - k: backport_schema_to_openapi_3_0(v) - for k, v in schema[dict_key].items() - } - for x_of_key in ("allOf", "anyOf", "oneOf"): - if x_of_key in schema: - schema[x_of_key] = list( - map(backport_schema_to_openapi_3_0, schema[x_of_key]) - ) - if len(schema[x_of_key]) == 2: - x_of_copy = [s for s in schema[x_of_key] if s != {"nullable": True}] - if len(x_of_copy) == 1: - schema.pop(x_of_key) - schema.update(x_of_copy[0]) - schema["nullable"] = True - return schema diff --git a/s2gos-common/src/s2gos_common/service.py b/s2gos-common/src/s2gos_common/service.py deleted file mode 100644 index 38e17a1..0000000 --- a/s2gos-common/src/s2gos_common/service.py +++ /dev/null @@ -1,99 +0,0 @@ -# generated by gen_server.py: -# filename: service.py: -# timestamp: 2025-10-01T16:12:52.122326 - -from abc import ABC, abstractmethod - -from .models import ( - Capabilities, - ConformanceDeclaration, - JobInfo, - JobList, - JobResults, - ProcessDescription, - ProcessList, - ProcessRequest, -) - - -class Service(ABC): - @abstractmethod - async def get_capabilities(self, *args, **kwargs) -> Capabilities: - """The landing page provides links to the: - * The OpenAPI-definition (no fixed path), - * The Conformance statements (path /conformance), - * The processes metadata (path /processes), - * The endpoint for job monitoring (path /jobs). - - For more information, see [Section 7.2](https://docs.ogc.org/is/18-062/18-062.html#sc_landing_page).""" - - @abstractmethod - async def get_conformance(self, *args, **kwargs) -> ConformanceDeclaration: - """A list of all conformance classes, specified in a standard, that the server conforms to. - - | Conformance class | URI | - |-----------|-------| - |Core|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/core| - |OGC Process Description|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/ogc-process-description| - |JSON|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/json| - |HTML|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/html| - |OpenAPI Specification 3.0|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/oas30| - |Job list|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/job-list| - |Callback|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/callback| - |Dismiss|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/dismiss| - - For more information, see [Section 7.4](https://docs.ogc.org/is/18-062/18-062.html#sc_conformance_classes). - """ - - @abstractmethod - async def get_processes(self, *args, **kwargs) -> ProcessList: - """The list of processes contains a summary of each process the OGC API - Processes offers, including the link to a more detailed description of the process. - - For more information, see [Section 7.9](https://docs.ogc.org/is/18-062/18-062.html#sc_process_list). - """ - - @abstractmethod - async def get_process(self, process_id: str, *args, **kwargs) -> ProcessDescription: - """The process description contains information about inputs and outputs and a link to the execution-endpoint for the process. The Core does not mandate the use of a specific process description to specify the interface of a process. That said, the Core requirements class makes the following recommendation: - - Implementations SHOULD consider supporting the OGC process description. - - For more information, see [Section 7.10](https://docs.ogc.org/is/18-062/18-062.html#sc_process_description). - """ - - @abstractmethod - async def execute_process( - self, process_id: str, process_request: ProcessRequest, *args, **kwargs - ) -> JobInfo: - """Create a new job. - - For more information, see [Section 7.11](https://docs.ogc.org/is/18-062/18-062.html#sc_create_job). - """ - - @abstractmethod - async def get_jobs(self, *args, **kwargs) -> JobList: - """Lists available jobs. - - For more information, see [Section 11](https://docs.ogc.org/is/18-062/18-062.html#sc_job_list). - """ - - @abstractmethod - async def get_job(self, job_id: str, *args, **kwargs) -> JobInfo: - """Shows the status of a job. - - For more information, see [Section 7.12](https://docs.ogc.org/is/18-062/18-062.html#sc_retrieve_status_info). - """ - - @abstractmethod - async def dismiss_job(self, job_id: str, *args, **kwargs) -> JobInfo: - """Cancel a job execution and remove it from the jobs list. - - For more information, see [Section 13](https://docs.ogc.org/is/18-062/18-062.html#Dismiss). - """ - - @abstractmethod - async def get_job_results(self, job_id: str, *args, **kwargs) -> JobResults: - """Lists available results of a job. In case of a failure, lists errors instead. - - For more information, see [Section 7.13](https://docs.ogc.org/is/18-062/18-062.html#sc_retrieve_job_results). - """ diff --git a/s2gos-common/src/s2gos_common/util/__init__.py b/s2gos-common/src/s2gos_common/util/__init__.py deleted file mode 100644 index 22d05e1..0000000 --- a/s2gos-common/src/s2gos_common/util/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. diff --git a/s2gos-common/src/s2gos_common/util/cli/__init__.py b/s2gos-common/src/s2gos_common/util/cli/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-common/src/s2gos_common/util/cli/group.py b/s2gos-common/src/s2gos_common/util/cli/group.py deleted file mode 100644 index 0f7fbbb..0000000 --- a/s2gos-common/src/s2gos_common/util/cli/group.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import click -import typer.core - - -class AliasedGroup(typer.core.TyperGroup): - """ - A group that accepts command aliases created from the - first letters of the words after splitting a command name - at hyphens. - """ - - @staticmethod - def to_alias(name: str): - """Create a short alias for given command name.""" - return "".join(map(lambda n: n[0], name.split("-"))) - - def get_command(self, ctx, cmd_name): - rv = super().get_command(ctx, cmd_name) - - if rv is not None: - return rv - - matches = [ - x - for x in self.list_commands(ctx) - if cmd_name == x or cmd_name == self.to_alias(x) - ] - - if not matches: - return None - - if len(matches) == 1: - return click.Group.get_command(self, ctx, matches[0]) - - ctx.fail(f"Too many matches: {', '.join(sorted(matches))}") - - def resolve_command( - self, ctx, args - ) -> tuple[str | None, click.Command | None, list[str]]: - # always return the full command name - _, cmd, args = super().resolve_command(ctx, args) - if cmd is not None: - return cmd.name, cmd, args - else: - return None, None, args - - def list_commands(self, ctx): - # prevent alphabetical ordering - return list(self.commands) diff --git a/s2gos-common/src/s2gos_common/util/cli/parameters.py b/s2gos-common/src/s2gos_common/util/cli/parameters.py deleted file mode 100644 index caf7273..0000000 --- a/s2gos-common/src/s2gos_common/util/cli/parameters.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import typer - -# See also s2gos-client/src/s2gos_client/cli/cli.py -PROCESS_ID_ARGUMENT = typer.Argument( - help="Process identifier.", -) - -# See also s2gos-client/src/s2gos_client/cli/cli.py -REQUEST_INPUT_OPTION = typer.Option( - "--input", - "-i", - help="Process input value.", - metavar="[NAME=VALUE]...", -) - -# See also s2gos-client/src/s2gos_client/cli/cli.py -REQUEST_SUBSCRIBER_OPTION = typer.Option( - "--subscriber", - "-s", - help="Process subscriber URL.", - metavar="[NAME=URL]...", -) - -DOT_PATH_OPTION = typer.Option( - ..., - "--dotpath", - "-d", - is_flag=True, - help="Input names use dot-path notion to encode nested values, e.g., `-i scene.colors.bg=red`.", -) - -# See also s2gos-client/src/s2gos_client/cli/cli.py -REQUEST_FILE_OPTION = typer.Option( - ..., - "--request", - "-r", - help="Execution request file. Use `-` to read from .", - metavar="PATH", -) diff --git a/s2gos-common/src/s2gos_common/util/dynimp.py b/s2gos-common/src/s2gos_common/util/dynimp.py deleted file mode 100644 index 8acbe8d..0000000 --- a/s2gos-common/src/s2gos_common/util/dynimp.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import importlib -from typing import Optional, TypeVar - -_type_fn = type - -T = TypeVar("T") - - -# noinspection PyShadowingBuiltins -def import_value( - ref: str, - *, - type: type[T], - name: str, - example: Optional[str] = None, -) -> T: - """ - Dynamically import a value given by its reference `ref`. - - Args: - ref: A value reference of the form ":". - type: Expected type of the reference - name: Name of the reference - example: An example reference (for error messages) - - Returns: - The imported value. - - Raises: - ValueError: if the `ref` syntax is invalid, or the module - cannot be imported, or attribute cannot be found. - TypeError: if the loaded value is not an instance of - the expected type. - """ - example = example or "path.to.module:attr" - - try: - module_name, attr_ref = ref.split(":", maxsplit=1) - except ValueError: - raise ValueError( - f"The {name} reference must be passed in the form {example!r}, " - f"but got {ref!r}." - ) - - try: - module = importlib.import_module(module_name) - except ImportError: - raise ValueError(f"Cannot import module {module_name!r}.") - - value = module - partial_spec = module_name - for i, attr_name in enumerate(attr_ref.split(".")): - try: - value = getattr(value, attr_ref) - except AttributeError: - raise ValueError( - f"{'Module' if i == 0 else 'Object'} {partial_spec!r} " - f"has no attribute {attr_name!r}." - ) - partial_spec += (":" if i == 0 else ".") + attr_name - - if not isinstance(value, type): - raise TypeError( - f"The reference {ref!r} should refer to a {name} of type " - f"{type.__name__}, but got type {_type_fn(value).__name__}." - ) - - return value diff --git a/s2gos-common/src/s2gos_common/util/obj.py b/s2gos-common/src/s2gos_common/util/obj.py deleted file mode 100644 index 8707db3..0000000 --- a/s2gos-common/src/s2gos_common/util/obj.py +++ /dev/null @@ -1,138 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Any - - -def flatten_obj( - obj: Any, *, parent_key: str = "", sep: str = ".", flatten_lists: bool = False -) -> dict[str, Any]: - return _flatten_obj( - obj, parent_key=parent_key, sep=sep, flatten_lists=flatten_lists - ) - - -def _flatten_obj( - obj: Any, - parent_key: str = "", - sep: str = ".", - flatten_lists: bool = False, -) -> dict[str, Any]: - """ - Flatten nested dicts/lists into a flat dict with sep-delimited keys. - - Args: - obj: The nested structure (dict, list, or scalar). - parent_key: Internal recursion prefix for keys. - sep: Separator string for flattened keys. - flatten_lists: If True, expand lists into indexed keys (default). - If False, keep lists as values (without flattening inside). - - Returns: - A flat dictionary mapping sep-delimited keys to values. - """ - items: dict[str, Any] = {} - - if isinstance(obj, dict) and len(obj) > 0: - for k, v in obj.items(): - _update_flattened_items(k, v, parent_key, flatten_lists, sep, items) - elif isinstance(obj, list) and len(obj) > 0 and flatten_lists: - for i, v in enumerate(obj): - if v is None: # skip None placeholders - continue - _update_flattened_items(i, v, parent_key, flatten_lists, sep, items) - elif parent_key: - items[parent_key] = obj - - return items - - -def _update_flattened_items( - k, - v, - parent_key: str, - flatten_lists: bool, - sep: str, - items: dict[str, Any], -): - new_key = f"{parent_key}{sep}{k}" if parent_key else str(k) - flattened_v = _flatten_obj( - v, parent_key=new_key, flatten_lists=flatten_lists, sep=sep - ) - items.update(flattened_v) - - -def nest_dict(flatted_dict: dict[str, Any], *, sep: str = ".") -> dict[str, Any]: - """Nest a flat dict with sep-delimited keys back into a dicts.""" - root = nest_obj(flatted_dict, sep=sep, root={}) - assert isinstance(root, dict) - return root - - -def nest_obj( - flatted_dict: dict[str, Any], - *, - sep: str = ".", - root: dict[str, Any] | list[Any] | None = None, -) -> dict[str, Any] | list[Any] | None: - """Nest a flat dict with sep-delimited keys back into dicts/lists.""" - # TODO: respect flatten_lists - for k, v in flatted_dict.items(): - root = _nest_one(root, k, v, sep=sep) - return root - - -def _nest_one( - root: dict[str, Any] | list[Any] | None, - name: str, - value: Any, - sep: str = ".", -) -> dict[str, Any] | list[Any] | None: - keys = _parse_path(name, sep) - - current: Any = None - prev: Any | None = None - - for i, key_or_index in enumerate(keys): - if root is None: - root = [] if isinstance(key_or_index, int) else {} - if i == 0: - current = root - if current is None and prev is not None: - current = prev[keys[i - 1]] = [] if isinstance(key_or_index, int) else {} - prev = current - current = _prepare_path(prev, key_or_index) - - assert prev is not None - prev[keys[-1]] = value - return root - - -def _prepare_path(current: dict[str, Any] | list[Any], key_or_index: str | int) -> Any: - if isinstance(current, list): - if not isinstance(key_or_index, int): - raise TypeError( - f"expected index of type int, got {type(key_or_index).__name__}" - ) - index: int = key_or_index - current_list: list[Any] = current - while len(current_list) <= index: - current_list.append(None) # This is a Fill-value - return current_list[index] - elif isinstance(current, dict): - if isinstance(key_or_index, int): - raise TypeError( - f"expected key of type str, got {type(key_or_index).__name__}" - ) - key: str = key_or_index - current_dict: dict[str, Any] = current - if key not in current_dict: - current_dict[key] = None # This is a Fill-value - return current_dict[key] - raise TypeError(f"expected a list or a dict, got {type(current).__name__}") - - -def _parse_path(name: str, sep: str = ".") -> list[str | int]: - keys: list[str] = name.split(sep) - return [(int(key) if all(c.isdigit() for c in key) else key) for key in keys] diff --git a/s2gos-common/src/s2gos_common/util/testing.py b/s2gos-common/src/s2gos_common/util/testing.py deleted file mode 100644 index 8ad50be..0000000 --- a/s2gos-common/src/s2gos_common/util/testing.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import os -from collections.abc import Generator -from contextlib import contextmanager -from typing import Callable - -from pydantic import BaseModel - - -# noinspection PyAttributeOutsideInit,PyUnresolvedReferences,PyPep8Naming -class BaseModelMixin: - """ - Add to test classes to get the `assertBaseModelEqual` method. - """ - - def assertBaseModelEqual(self, a: BaseModel, b: BaseModel): - """Assert that two `BaseModel`s are equal.""" - self.maxDiff = None - self.assertIsInstance(a, BaseModel) # type: ignore[attr-defined] - self.assertIsInstance(b, BaseModel) # type: ignore[attr-defined] - self.assertIs(b.__class__, a.__class__) # type: ignore[attr-defined] - a_value = a.model_dump( - mode="json", by_alias=True, exclude_none=True, exclude_defaults=True - ) - b_value = b.model_dump( - mode="json", by_alias=True, exclude_none=True, exclude_defaults=True - ) - self.assertEqual(a_value, b_value) # type: ignore[attr-defined] - - -@contextmanager -def set_env_cm(**new_env: str | None) -> Generator[dict[str, str | None]]: - """Run the code in the block with a new environment `new_env`.""" - restore_env = set_env(**new_env) - try: - yield new_env - finally: - restore_env() - - -def set_env(**new_env: str | None) -> Callable[[], None]: - """ - Set the new environment in `new_env` and return a no-arg - function to restore the old environment. - """ - old_env = {k: os.environ.get(k) for k in new_env.keys()} - - def restore_env(): - for ko, vo in old_env.items(): - if vo is not None: - os.environ[ko] = vo - elif ko in os.environ: - del os.environ[ko] - - for kn, vn in new_env.items(): - if vn is not None: - os.environ[kn] = vn - elif kn in os.environ: - del os.environ[kn] - - return restore_env diff --git a/s2gos-common/src/tests/__init__.py b/s2gos-common/src/tests/__init__.py deleted file mode 100644 index 22d05e1..0000000 --- a/s2gos-common/src/tests/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. diff --git a/s2gos-common/src/tests/process/__init__.py b/s2gos-common/src/tests/process/__init__.py deleted file mode 100644 index 22d05e1..0000000 --- a/s2gos-common/src/tests/process/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. diff --git a/s2gos-common/src/tests/process/cli/__init__.py b/s2gos-common/src/tests/process/cli/__init__.py deleted file mode 100644 index 22d05e1..0000000 --- a/s2gos-common/src/tests/process/cli/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. diff --git a/s2gos-common/src/tests/process/cli/test_cli.py b/s2gos-common/src/tests/process/cli/test_cli.py deleted file mode 100644 index 6d95393..0000000 --- a/s2gos-common/src/tests/process/cli/test_cli.py +++ /dev/null @@ -1,186 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -import typer.testing - -from s2gos_common.process import ProcessRegistry -from s2gos_common.process.cli.cli import get_cli - -registry = ProcessRegistry() - - -@registry.process(id="f1") -def f1(a: int, b: str, c: float) -> str: - return f"{a}, {b}, {c}" - - -@registry.process(id="f2") -def f2(x: bool, y: str, z: float) -> tuple: - if y == "bibo": - raise ValueError("y must not be bibo") - return x, y, z - - -# noinspection PyUnresolvedReferences -class CliTestMixin: - @classmethod - def get_cli(cls) -> typer.Typer: - raise NotImplementedError - - @classmethod - def invoke_cli(cls, *args: str) -> typer.testing.Result: - runner = typer.testing.CliRunner() - return runner.invoke(cls.get_cli(), args) - - def test_execute_process_f1_success(self): - result = self.invoke_cli( - "execute-process", "f1", "-i", "a=0", "-i", "b=bibo", "-i", "c=0.2" - ) - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual( - '{\n "return_value": "0, bibo, 0.2"\n}\n', - result.output, - ) - - def test_execute_process_f2_success(self): - result = self.invoke_cli( - "execute-process", "f2", "-i", "x=true", "-i", "y=pippo", "-i", "z=0.3" - ) - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual( - '{\n "return_value": [\n true,\n "pippo",\n 0.3\n ]\n}\n', - result.output, - ) - - def test_execute_process_f2_fail(self): - result = self.invoke_cli( - "execute-process", "f2", "-i", "x=true", "-i", "y=bibo", "-i", "z=1.8" - ) - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertIn(' "processID": "f2",', result.output) - self.assertIn(' "status": "failed",', result.output) - self.assertIn(' "message": "y must not be bibo",', result.output) - - def test_execute_process_fail(self): - result = self.invoke_cli("execute-process", "f5") - self.assertEqual(1, result.exit_code, msg=self.get_result_msg(result)) - self.assertIn("Process 'f5' not found.", result.output) - - def test_list_processes(self): - result = self.invoke_cli("list-processes") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual( - ( - "{\n" - ' "f1": {\n' - ' "id": "f1",\n' - ' "version": "0.0.0"\n' - " },\n" - ' "f2": {\n' - ' "id": "f2",\n' - ' "version": "0.0.0"\n' - " }\n" - "}\n" - ), - result.output, - ) - - def test_get_process_ok(self): - result = self.invoke_cli("get-process", "f2") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertEqual( - ( - "{\n" - ' "id": "f2",\n' - ' "version": "0.0.0",\n' - ' "inputs": {\n' - ' "x": {\n' - ' "title": "X",\n' - ' "schema": {\n' - ' "type": "boolean"\n' - " }\n" - " },\n" - ' "y": {\n' - ' "title": "Y",\n' - ' "schema": {\n' - ' "type": "string"\n' - " }\n" - " },\n" - ' "z": {\n' - ' "title": "Z",\n' - ' "schema": {\n' - ' "type": "number"\n' - " }\n" - " }\n" - " },\n" - ' "outputs": {\n' - ' "return_value": {\n' - ' "title": "Return Value",\n' - ' "schema": {\n' - ' "type": "array",\n' - ' "items": {}\n' - " }\n" - " }\n" - " }\n" - "}\n" - ), - result.output, - ) - - def test_get_process_fail(self): - result = self.invoke_cli("get-process", "f9") - self.assertEqual(1, result.exit_code, msg=self.get_result_msg(result)) - self.assertIn("Process 'f9' not found.", result.output) - - def test_help(self): - result = self.invoke_cli("--help") - self.assertEqual(0, result.exit_code, msg=self.get_result_msg(result)) - self.assertIn( - "Command-line interface for process description and execution", - result.output, - ) - - @classmethod - def get_result_msg(cls, result: typer.testing.Result): - if result.exit_code != 0: - return f"output was: [{result.output}]\nstderr was: [{result.stderr}]" - else: - return None - - -class AppWithRealClientTest(TestCase): - def test_get_processes(self): - """Test code in app so that the non-mocked Client is used.""" - cli = CliRegistryTest.get_cli() - runner = typer.testing.CliRunner() - result = runner.invoke(cli, ["list-processes"]) - # May succeed if dev server is running - self.assertTrue( - result.exit_code in (0, 1), msg=f"exit code was {result.exit_code}" - ) - if result.exit_code != 0: - print(result.output) - - -class CliRegistryTest(CliTestMixin, TestCase): - @classmethod - def get_cli(cls): - return get_cli(registry) - - -class CliRegistryRefTest(CliTestMixin, TestCase): - @classmethod - def get_cli(cls): - return get_cli("tests.process.cli.test_cli:registry") - - -class CliRegistryGetterTest(CliTestMixin, TestCase): - @classmethod - def get_cli(cls): - def get_registry(): - return registry - - return get_cli(get_registry) diff --git a/s2gos-common/src/tests/process/test_job.py b/s2gos-common/src/tests/process/test_job.py deleted file mode 100644 index 941ed6d..0000000 --- a/s2gos-common/src/tests/process/test_job.py +++ /dev/null @@ -1,257 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -import pydantic -import pytest - -from s2gos_common.models import JobResults, JobStatus, ProcessRequest, Subscriber -from s2gos_common.process import Process -from s2gos_common.process.job import ( - Job, - JobCancelledException, - JobContext, - NullJobContext, -) - -from .test_process import f1 - - -def fn_success(x: int, y: int) -> int: - return x * y - - -def fn_success_with_defaults(x: int = 0, y: int = 0) -> int: - return x + y - - -def fn_success_body_ctx(path: str) -> str: - ctx = JobContext.get() - ctx.check_cancelled() - ctx.report_progress(progress=0) - ctx.report_progress(progress=50, message="Almost done") - ctx.report_progress(progress=100) - return path + "/result1.zarr" - - -def fn_success_arg_ctx(ctx: JobContext, path: str) -> str: - ctx.check_cancelled() - ctx.report_progress(progress=0) - ctx.report_progress(progress=50, message="Almost done") - ctx.report_progress(progress=100) - return path + "/result2.zarr" - - -class Params(pydantic.BaseModel): - p1: bool - p2: float - p3: str - - -def fn_success_inputs_arg(ctx: JobContext, params: Params) -> str: - ctx.report_progress(message="Done!") - return f"{params.p1!r}-{params.p2!r}-{params.p3!r}" - - -# noinspection PyUnusedLocal -def fn_cancel_exc(path: str) -> str: - raise JobCancelledException - - -# noinspection PyUnusedLocal -def fn_exc(path: str) -> str: - raise OSError("File not found") - - -class JobTest(TestCase): - def test_ctor(self): - job = Job.create( - process=Process.create(fn_success, id="fn_success"), - job_id="job_27", - request=ProcessRequest(inputs={"x": True, "y": 2}), - ) - self.assertEqual("fn_success", job.job_info.processID) - self.assertEqual("job_27", job.job_info.jobID) - self.assertEqual(None, job.job_info.progress) - self.assertEqual({"x": True, "y": 2}, job.function_kwargs) - - def test_context(self): - job = Job.create( - process=Process.create(fn_success, id="fn_success"), - job_id="job_27", - request=ProcessRequest(inputs={"x": False, "y": 2}), - ) - self.assertEqual(False, job.is_cancelled()) - self.assertEqual(None, job.check_cancelled()) - job.report_progress(progress=35, message="2/6 input files downloaded") - self.assertEqual(35, job.job_info.progress) - self.assertEqual("2/6 input files downloaded", job.job_info.message) - job.report_progress(message="3/6 input files downloaded") - self.assertEqual(35, job.job_info.progress) - self.assertEqual("3/6 input files downloaded", job.job_info.message) - job.report_progress(progress=40) - self.assertEqual(40, job.job_info.progress) - self.assertEqual("3/6 input files downloaded", job.job_info.message) - - job.cancel() - self.assertEqual(True, job.is_cancelled()) - with pytest.raises(JobCancelledException): - job.check_cancelled() - self.assertEqual(40, job.job_info.progress) - self.assertEqual("3/6 input files downloaded", job.job_info.message) - - def test_run_success(self): - job = Job.create( - process=Process.create(fn_success, id="fn_success"), - job_id="job_41", - request=ProcessRequest(inputs={"x": 3, "y": 9}), - ) - job_results = job.run() - # noinspection PyArgumentList - self.assertEqual(JobResults({"return_value": 27}), job_results) - self.assertEqual(JobStatus.successful, job.job_info.status) - self.assertEqual(None, job.job_info.progress) - self.assertEqual(None, job.job_info.message) - - def test_run_success_with_defaults(self): - job = Job.create( - process=Process.create( - fn_success_with_defaults, id="fn_success_with_defaults" - ), - job_id="job_652", - request=ProcessRequest(inputs={"y": 13}), - ) - job_results = job.run() - # noinspection PyArgumentList - self.assertEqual(JobResults({"return_value": 13}), job_results) - self.assertEqual(JobStatus.successful, job.job_info.status) - self.assertEqual(None, job.job_info.progress) - self.assertEqual(None, job.job_info.message) - - def test_run_success_body_ctx_report(self): - job = Job.create( - process=Process.create(fn_success_body_ctx, id="fn_success_body_ctx"), - job_id="job_41", - request=ProcessRequest(inputs={"path": "outputs"}), - ) - job_results = job.run() - # noinspection PyArgumentList - self.assertEqual( - JobResults({"return_value": "outputs/result1.zarr"}), job_results - ) - self.assertEqual(JobStatus.successful, job.job_info.status) - self.assertEqual(100, job.job_info.progress) - self.assertEqual("Almost done", job.job_info.message) - - def test_run_success_arg_ctx_report(self): - job = Job.create( - process=Process.create(fn_success_arg_ctx, id="fn_success_arg_ctx"), - job_id="job_42", - request=ProcessRequest(inputs={"path": "outputs"}), - ) - job_results = job.run() - # noinspection PyArgumentList - self.assertEqual( - JobResults({"return_value": "outputs/result2.zarr"}), job_results - ) - self.assertEqual(JobStatus.successful, job.job_info.status) - self.assertEqual(100, job.job_info.progress) - self.assertEqual("Almost done", job.job_info.message) - - def test_run_success_input_args(self): - job = Job.create( - process=Process.create( - fn_success_inputs_arg, id="fn_success_inputs_arg", inputs_arg=True - ), - job_id="job_42", - request=ProcessRequest(inputs={"p1": True, "p2": 0.5, "p3": "abc"}), - ) - job_results = job.run() - # noinspection PyArgumentList - self.assertEqual(JobResults({"return_value": "True-0.5-'abc'"}), job_results) - self.assertEqual(JobStatus.successful, job.job_info.status) - self.assertEqual(None, job.job_info.progress) - self.assertEqual("Done!", job.job_info.message) - - def test_run_exc(self): - job = Job.create( - process=Process.create(fn_exc, id="fn_exc"), - job_id="job_41", - request=ProcessRequest(inputs={"path": "outputs"}), - ) - result = job.run() - self.assertEqual(None, result) - self.assertEqual(JobStatus.failed, job.job_info.status) - - def test_run_failed(self): - job = Job.create( - process=Process.create(fn_cancel_exc, id="fn_cancel_exc"), - job_id="job_41", - request=ProcessRequest(inputs={"path": "outputs"}), - ) - result = job.run() - self.assertEqual(None, result) - self.assertEqual(JobStatus.dismissed, job.job_info.status) - - def test_run_success_report_with_subscriber(self): - job = Job.create( - process=Process.create(fn_success_body_ctx, id="fn_success_report"), - job_id="job_3092", - request=ProcessRequest( - inputs={"path": "outputs"}, - subscriber=Subscriber( - **{ - "successUri": "http://localhost:7000/cb/success", - "inProgressUri": "http://localhost:7000/cb/progress", - "failedUri": "http://localhost:7000/cb/failed", - } - ), - ), - ) - result = job.run() - self.assertIsInstance(result, JobResults) - self.assertEqual(JobStatus.successful, job.job_info.status) - - def test_run_exc_with_subscriber(self): - job = Job.create( - process=Process.create(fn_exc, id="fn_exc"), - job_id="job_3092", - request=ProcessRequest( - inputs={"path": "outputs"}, - subscriber=Subscriber( - **{ - "successUri": "http://localhost:7000/cb/success", - "inProgressUri": "http://localhost:7000/cb/progress", - "failedUri": "http://localhost:7000/cb/failed", - } - ), - ), - ) - result = job.run() - self.assertEqual(None, result) - self.assertEqual(JobStatus.failed, job.job_info.status) - - -class GetJobContextTest(TestCase): - def test_null(self): - job_context = JobContext.get() - self.assertIsInstance(job_context, NullJobContext) - - def test_valid(self): - __job_context__ = Job( # noqa: F841 - process=Process.create(f1), - job_id="b", - function_kwargs={"x": 4}, - ) - value = JobContext.get() - self.assertIs(__job_context__, value) - - -class NullJobContextTest(TestCase): - def test_it(self): - job_context = NullJobContext() - self.assertFalse(job_context.report_progress(progress=85)) - self.assertFalse(job_context.is_cancelled()) - self.assertFalse(job_context.check_cancelled()) diff --git a/s2gos-common/src/tests/process/test_process.py b/s2gos-common/src/tests/process/test_process.py deleted file mode 100644 index c3f6f87..0000000 --- a/s2gos-common/src/tests/process/test_process.py +++ /dev/null @@ -1,449 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Annotated -from unittest import TestCase - -import pydantic -import pytest -from pydantic import BaseModel, Field - -from s2gos_common.models import ( - DataType, - InputDescription, - OutputDescription, - ProcessDescription, - Schema, -) -from s2gos_common.process import JobContext, Process -from s2gos_common.util.testing import BaseModelMixin - - -def f1(x: float, y: float) -> float: - """This is f1.""" - return 2.0 * y if x else 0.5 * y - - -def f2(a: bool | None, b: float | bool) -> tuple[float, float]: - """This is f2.""" - return (2.0 * b, 0.5 * b) if a else (0.5 * b, 2.0 * b) - - -class Point(BaseModel): - """A 2-D point.""" - - x: float = Field(0.0, title="X-coordinate") - y: float = Field(0.0, title="Y-coordinate") - - -def f3(point1: Point, point2: Point) -> Point: - """This is f3.""" - return Point(x=(point2.x - point1.x), y=(point2.y - point1.y)) - - -def f4(ctx: JobContext, flag: bool) -> str: - """This is f3.""" - return f"{type(ctx).__name__}-{flag}" - - -def f4_fail_ctx(ctx: JobContext, flag: bool, ctx2: JobContext) -> str: - """This is f4 with two context definitions -> illegal.""" - return f"{type(ctx).__name__}-{flag}" - - -class InputArg(pydantic.BaseModel): - arg1: Annotated[int, pydantic.Field(..., ge=0, le=1)] - arg2: str - kwarg1: Annotated[int, pydantic.Field(..., ge=0, le=1)] = 0 - kwarg2: str = "" - - -def f5(ctx: JobContext, arg: InputArg) -> str: - """This is f5.""" - return f"{type(ctx).__name__}-{arg.model_dump_json()}" - - -def f5_wrong_input_arg_type(ctx: JobContext, arg: int) -> str: - """This is f5 with 'u' being an int --> raise type error""" - return f"{type(ctx).__name__}-{arg}" - - -def f5_too_many_args(ctx: JobContext, u: InputArg, v: float) -> str: - """This is f5 with 'u' being input arg --> raise v is illegal""" - return f"{type(ctx).__name__}-{u.model_dump_json()}-{v}" - - -# noinspection PyMethodMayBeStatic -class RegisteredProcessTest(BaseModelMixin, TestCase): - # noinspection PyMethodMayBeStatic - def test_create_fail(self): - with pytest.raises(TypeError, match="function argument must be callable"): - # noinspection PyTypeChecker - Process.create(42) - - def test_create_f1(self): - process = Process.create(f1) - self.assertIsInstance(process, Process) - self.assertIs(f1, process.function) - proc_desc = process.description - self.assertIsInstance(proc_desc, ProcessDescription) - self.assertEqual("tests.process.test_process:f1", proc_desc.id) - self.assertEqual("0.0.0", proc_desc.version) - self.assertEqual(None, proc_desc.title) - self.assertEqual("This is f1.", proc_desc.description) - proc_inputs = proc_desc.inputs - proc_outputs = proc_desc.outputs - self.assertIsInstance(proc_inputs, dict) - self.assertIsInstance(proc_outputs, dict) - self.assertEqual(["x", "y"], list(proc_inputs.keys())) - self.assertEqual(["return_value"], list(proc_outputs.keys())) - self.assertBaseModelEqual( - InputDescription(title="X", schema=Schema(type=DataType.number)), - proc_inputs["x"], - ) - self.assertBaseModelEqual( - InputDescription(title="Y", schema=Schema(type=DataType.number)), - proc_inputs["y"], - ) - self.assertEqual( - OutputDescription( - title="Return Value", - schema=Schema(type=DataType.number), - ), - proc_outputs["return_value"], - ) - - # noinspection PyMethodMayBeStatic - def test_create_f1_with_input_fields(self): - process = Process.create( - f1, - input_fields={ - "x": Field(title="A wonderful X", ge=0.0), - "y": Field(title="A beautiful Y", lt=1.0), - }, - ) - self.assertIsInstance(process, Process) - self.assertIs(f1, process.function) - self.assertEqual(None, process.job_ctx_arg) - proc_desc = process.description - proc_inputs = proc_desc.inputs - proc_outputs = proc_desc.outputs - self.assertIsInstance(proc_inputs, dict) - self.assertIsInstance(proc_outputs, dict) - self.assertEqual(["x", "y"], list(proc_inputs.keys())) - self.assertEqual(["return_value"], list(proc_outputs.keys())) - self.assertBaseModelEqual( - InputDescription( - title="A wonderful X", schema=Schema(type=DataType.number, minimum=0.0) - ), - proc_inputs["x"], - ) - self.assertBaseModelEqual( - InputDescription( - title="A beautiful Y", - schema=Schema(type=DataType.number, exclusiveMaximum=1.0), - ), - proc_inputs["y"], - ) - self.assertEqual( - OutputDescription( - title="Return Value", - schema=Schema(type=DataType.number), - ), - proc_outputs["return_value"], - ) - - def test_create_f2(self): - process = Process.create(f2) - self.assertIsInstance(process, Process) - self.assertIs(f2, process.function) - self.assertEqual(None, process.job_ctx_arg) - proc_desc = process.description - self.assertIsInstance(proc_desc, ProcessDescription) - self.assertEqual("tests.process.test_process:f2", proc_desc.id) - self.assertEqual("0.0.0", proc_desc.version) - self.assertEqual(None, proc_desc.title) - self.assertEqual("This is f2.", proc_desc.description) - proc_inputs = proc_desc.inputs - proc_outputs = proc_desc.outputs - self.assertIsInstance(proc_inputs, dict) - self.assertIsInstance(proc_outputs, dict) - self.assertEqual(["a", "b"], list(proc_inputs.keys())) - self.assertEqual(["return_value"], list(proc_outputs.keys())) - self.assertBaseModelEqual( - InputDescription( - title="A", - schema=Schema(type=DataType.boolean, nullable=True), - ), - proc_inputs["a"], - ) - self.assertBaseModelEqual( - InputDescription( - title="B", - schema=Schema( - anyOf=[ - Schema(type=DataType.number), - Schema(type=DataType.boolean), - ], - ), - ), - proc_inputs["b"], - ) - self.assertBaseModelEqual( - OutputDescription( - title="Return Value", - schema=Schema( - type=DataType.array, - items=Schema(type="number"), - minItems=2, - maxItems=2, - ), - ), - proc_outputs["return_value"], - ) - - def test_create_f2_with_one_output_field(self): - process = Process.create( - f2, - output_fields={ - "point": Field(title="A point (x, y)"), - }, - ) - self.assertIsInstance(process, Process) - self.assertIs(f2, process.function) - proc_desc = process.description - self.assertIsInstance(proc_desc, ProcessDescription) - self.assertEqual("tests.process.test_process:f2", proc_desc.id) - self.assertEqual("0.0.0", proc_desc.version) - self.assertEqual(None, proc_desc.title) - self.assertEqual("This is f2.", proc_desc.description) - proc_inputs = proc_desc.inputs - proc_outputs = proc_desc.outputs - self.assertIsInstance(proc_inputs, dict) - self.assertIsInstance(proc_outputs, dict) - self.assertEqual(["a", "b"], list(proc_inputs.keys())) - self.assertEqual(["point"], list(proc_outputs.keys())) - self.assertBaseModelEqual( - OutputDescription( - title="A point (x, y)", - schema=Schema( - type=DataType.array, - items=Schema(type="number"), - minItems=2, - maxItems=2, - ), - ), - proc_outputs["point"], - ) - - def test_create_f2_with_two_output_fields(self): - process = Process.create( - f2, - output_fields={ - "x": Field(title="The X", ge=0.0), - "y": Field(title="The Y", lt=1.0), - }, - ) - self.assertIsInstance(process, Process) - self.assertIs(f2, process.function) - proc_desc = process.description - self.assertIsInstance(proc_desc, ProcessDescription) - self.assertEqual("tests.process.test_process:f2", proc_desc.id) - self.assertEqual("0.0.0", proc_desc.version) - self.assertEqual(None, proc_desc.title) - self.assertEqual("This is f2.", proc_desc.description) - proc_inputs = proc_desc.inputs - proc_outputs = proc_desc.outputs - self.assertIsInstance(proc_inputs, dict) - self.assertIsInstance(proc_outputs, dict) - self.assertEqual(["a", "b"], list(proc_inputs.keys())) - self.assertEqual(["x", "y"], list(proc_outputs.keys())) - self.assertBaseModelEqual( - OutputDescription( - title="The X", - schema=Schema(type=DataType.number, minimum=0.0), - ), - proc_outputs["x"], - ) - self.assertEqual( - OutputDescription( - title="The Y", - schema=Schema(type=DataType.number, exclusiveMaximum=1.0), - ), - proc_outputs["y"], - ) - - # noinspection PyMethodMayBeStatic - def test_create_with_illegal_f1_with_output_fields(self): - with pytest.raises( - TypeError, - match=( - r"function 'tests\.process\.test_process:f1': " - r"return type must be tuple\[\] with arguments" - ), - ): - Process.create( - f1, - output_fields={ - "x": Field(title="The X", ge=0.0), - "y": Field(title="The Y", lt=1.0), - }, - ) - - # noinspection PyMethodMayBeStatic - def test_create_f1_with_illegal_input_fields(self): - with pytest.raises( - ValueError, - match=( - r"function 'tests\.process\.test_process:f1': " - r"all input names must have corresponding parameter names; " - r"invalid input name\(s\)\: 'u', 'v'" - ), - ): - Process.create( - f1, - input_fields={ - "x": Field(title="The valid X", ge=0.0), - "y": Field(title="The valid Y", lt=1.0), - "u": Field(title="The illegal U"), - "v": Field(title="The illegal V"), - }, - ) - - # noinspection PyMethodMayBeStatic - def test_create_f2_with_illegal_output_fields(self): - with pytest.raises( - ValueError, - match=( - r"function 'tests\.process\.test_process:f2': " - r"number of outputs must match number of tuple\[\] arguments" - ), - ): - Process.create( - f2, - output_fields={ - "x": Field(title="The X", ge=0.0), - "y": Field(title="The Y", lt=1.0), - "z": Field(title="The Z"), - }, - ) - - def test_create_f1_with_props(self): - process = Process.create(f1, id="foo", version="1.0.2", title="My Foo") - self.assertIsInstance(process, Process) - self.assertIs(f1, process.function) - process_desc = process.description - self.assertIsInstance(process_desc, ProcessDescription) - self.assertEqual("foo", process_desc.id) - self.assertEqual("1.0.2", process_desc.version) - self.assertEqual("My Foo", process_desc.title) - self.assertEqual("This is f1.", process_desc.description) - self.assertIsInstance(process_desc.inputs, dict) - self.assertIsInstance(process_desc.outputs, dict) - - def test_create_f3(self): - process = Process.create(f3, id="f3") - self.assertIsInstance(process, Process) - self.assertEqual(None, process.job_ctx_arg) - self.assertEqual( - {"point1", "point2"}, - set(process.description.inputs.keys()), - ) - self.assertBaseModelEqual( - InputDescription( - title="Point", - description="A 2-D point.", - schema=Schema( - **{ - "type": "object", - "properties": { - "x": { - "type": "number", - "default": 0.0, - "title": "X-coordinate", - }, - "y": { - "type": "number", - "default": 0.0, - "title": "Y-coordinate", - }, - }, - } - ), - ), - process.description.inputs["point1"], - ) - - def test_create_f4(self): - process = Process.create(f4, id="f4") - self.assertIsInstance(process, Process) - self.assertIs(f4, process.function) - self.assertEqual("ctx", process.job_ctx_arg) - - def test_create_f4_fail_ctx(self): - with pytest.raises( - ValueError, - match="function '.*:f4_fail_ctx': only one parameter " - "can have type JobContext, but found 'ctx' and 'ctx2'", - ): - Process.create(f4_fail_ctx, id="f4_fail_ctx") - - def test_create_f5(self): - def assert_process_ok(p: Process): - self.assertIsInstance(p, Process) - self.assertIs(f5, p.function) - self.assertEqual("ctx", p.job_ctx_arg) - self.assertIsInstance(p.description, ProcessDescription) - self.assertIsInstance(p.description.inputs, dict) - return p.description.inputs - - def assert_input_arg_expanded(p: Process): - inputs = assert_process_ok(p) - self.assertEqual(["arg1", "arg2", "kwarg1", "kwarg2"], list(inputs.keys())) - self.assertTrue( - all(map(lambda v: isinstance(v, InputDescription), inputs.values())) - ) - - def assert_input_arg_untouched(p: Process): - inputs = assert_process_ok(p) - self.assertEqual(["arg"], list(inputs.keys())) - self.assertTrue( - all(map(lambda v: isinstance(v, InputDescription), inputs.values())) - ) - - process = Process.create(f5, id="f5", inputs_arg="arg") - assert_input_arg_expanded(process) - - process = Process.create(f5, id="f5", inputs_arg=True) - assert_input_arg_expanded(process) - - process = Process.create(f5, id="f5", inputs_arg=False) - assert_input_arg_untouched(process) - - def test_create_f5_with_wrong_input_arg(self): - with pytest.raises( - ValueError, - match="function '.*:f5': specified inputs argument is not an " - "argument of the function \(inputs_arg='x'\)", - ): - Process.create(f5, id="f5", inputs_arg="x") - - def test_create_f5_wrong_input_arg_type(self): - with pytest.raises( - TypeError, - match="function '.*:f5_wrong_input_arg_type': " - "type of inputs argument 'arg' must be a subclass " - "of pydantic.BaseModel", - ): - Process.create( - f5_wrong_input_arg_type, id="f5_wrong_input_arg_type", inputs_arg="arg" - ) - - def test_create_f5_too_many_args(self): - with pytest.raises( - ValueError, - match="function '.*:f5_too_many_args': the inputs argument must " - "be the only argument \(inputs_arg='u'\)", - ): - Process.create(f5_too_many_args, id="f5_too_many_args", inputs_arg="u") diff --git a/s2gos-common/src/tests/process/test_pydantic.py b/s2gos-common/src/tests/process/test_pydantic.py deleted file mode 100644 index c144c21..0000000 --- a/s2gos-common/src/tests/process/test_pydantic.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -import pydantic - - -class PydanticTest(TestCase): - """ - This test case ensures that pydantic behaves as expected - by own code in this package - """ - - def test_field_names_dont_need_to_be_python_identifiers(self): - model_class: type[pydantic.BaseModel] = pydantic.create_model( - "Pippo", **{"sur-name": str, "max.age": int} - ) - self.assertIsInstance(model_class, type) - self.assertTrue(issubclass(model_class, pydantic.BaseModel)) - self.assertEqual({"sur-name", "max.age"}, set(model_class.model_fields.keys())) - - # noinspection PyArgumentList - model_instance = model_class(**{"sur-name": "Bibo", "max.age": 100}) - self.assertEqual( - {"max.age": 100, "sur-name": "Bibo"}, model_instance.model_dump(mode="json") - ) diff --git a/s2gos-common/src/tests/process/test_registry.py b/s2gos-common/src/tests/process/test_registry.py deleted file mode 100644 index 7bffe79..0000000 --- a/s2gos-common/src/tests/process/test_registry.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from unittest import TestCase - -from s2gos_common.process import Process, ProcessRegistry -from s2gos_common.util.testing import BaseModelMixin - -from .test_process import f1, f2, f3 - - -class ProcessRegistryTest(BaseModelMixin, TestCase): - def test_register(self): - registry = ProcessRegistry() - self.assertEqual(None, registry.get("f1")) - self.assertEqual([], list(registry.keys())) - - # use as no-arg decorator - registry.process(f1) - self.assertEqual(1, len(registry)) - p1 = list(registry.values())[0] - self.assertIsInstance(p1, Process) - self.assertIs(p1, registry.get(p1.description.id)) - self.assertEqual(["tests.process.test_process:f1"], list(registry.keys())) - - # use as decorator with args - registry.process(id="f2")(f2) - self.assertEqual(2, len(registry)) - p1, p2 = registry.values() - self.assertIsInstance(p1, Process) - self.assertIsInstance(p2, Process) - self.assertIs(p1, registry.get(p1.description.id)) - self.assertIs(p2, registry.get(p2.description.id)) - self.assertEqual(["tests.process.test_process:f1", "f2"], list(registry.keys())) - - # use as function - registry.process(f3, id="my_fn3") - self.assertEqual(3, len(registry)) - p1, p2, p3 = registry.values() - self.assertIsInstance(p1, Process) - self.assertIsInstance(p2, Process) - self.assertIsInstance(p3, Process) - self.assertIs(p1, registry.get(p1.description.id)) - self.assertIs(p2, registry.get(p2.description.id)) - self.assertIs(p3, registry.get(p3.description.id)) - self.assertEqual( - ["tests.process.test_process:f1", "f2", "my_fn3"], list(registry.keys()) - ) diff --git a/s2gos-common/src/tests/process/test_reporter.py b/s2gos-common/src/tests/process/test_reporter.py deleted file mode 100644 index f03f260..0000000 --- a/s2gos-common/src/tests/process/test_reporter.py +++ /dev/null @@ -1,72 +0,0 @@ -import json -import time -import unittest -from unittest.mock import MagicMock, patch -from urllib import error - -from s2gos_common.process.reporter import CallbackReporter - - -class CallbackReporterTest(unittest.TestCase): - def setUp(self): - self.url = "http://localhost/callback" - - def test_report_and_stop_success(self): - with patch( - "urllib.request.urlopen", - return_value=MagicMock(__enter__=lambda s: s, __exit__=lambda s, *a: None), - ) as mock_urlopen: - reporter = CallbackReporter() - reporter.report(self.url, {"status": "ok"}) - reporter.stop() - self.assertTrue(mock_urlopen.called) - - def test_report_with_url_error(self): - with patch( - "urllib.request.urlopen", side_effect=error.URLError("fail") - ) as mock_urlopen: - reporter = CallbackReporter() - reporter.report(self.url, {"status": "fail"}) - reporter.stop() - self.assertEqual(mock_urlopen.call_count, 1) - - def test_report_with_http_error(self): - with patch( - "urllib.request.urlopen", - side_effect=error.HTTPError(self.url, 500, "error", hdrs=None, fp=None), - ) as mock_urlopen: - reporter = CallbackReporter() - reporter.report(self.url, {"status": "server error"}) - reporter.stop() - self.assertEqual(mock_urlopen.call_count, 1) - - def test_report_with_other_error(self): - with patch( - "urllib.request.urlopen", - side_effect=TypeError(self.url), - ) as mock_urlopen: - reporter = CallbackReporter() - reporter.report(self.url, {"status": "server error"}) - reporter.stop() - self.assertEqual(mock_urlopen.call_count, 1) - - def test_idle_thread_does_not_post(self): - with patch("urllib.request.urlopen") as mock_urlopen: - reporter = CallbackReporter() - time.sleep(1) - reporter.stop() - self.assertFalse(mock_urlopen.called) - - def test_multiple_reports_coalesce(self): - with patch( - "urllib.request.urlopen", - return_value=MagicMock(__enter__=lambda s: s, __exit__=lambda s, *a: None), - ) as mock_urlopen: - reporter = CallbackReporter() - reporter.report(self.url, {"status": "pending"}) - reporter.report(self.url, {"status": "running"}) - reporter.report(self.url, {"status": "completed"}) - reporter.stop() - args, _ = mock_urlopen.call_args - body = json.loads(args[0].data.decode("utf-8")) - self.assertEqual(body["status"], "completed") diff --git a/s2gos-common/src/tests/process/test_request.py b/s2gos-common/src/tests/process/test_request.py deleted file mode 100644 index 1e1f1c7..0000000 --- a/s2gos-common/src/tests/process/test_request.py +++ /dev/null @@ -1,371 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import os -from io import StringIO -from unittest import TestCase -from unittest.mock import patch - -import click -import pytest - -from s2gos_common.models import ( - InputDescription, - ProcessDescription, - ProcessRequest, - Schema, - Subscriber, -) -from s2gos_common.process.request import ExecutionRequest - -REQUEST_PATH = "test-request.yaml" - - -class ExecutionRequestTest(TestCase): - def tearDown(self): - if os.path.exists(REQUEST_PATH): - os.remove(REQUEST_PATH) - - def test_defaults(self): - request = ExecutionRequest(process_id="P16") - self.assertEqual( - ExecutionRequest( - process_id="P16", - dotpath=False, - inputs=None, - outputs=None, - subscriber=None, - ), - request, - ) - - def test_to_process_request(self): - request = ExecutionRequest(process_id="P16") - process_request = request.to_process_request() - self.assertIsInstance(process_request, ProcessRequest) - - def test_to_process_request_with_dotpath(self): - request = ExecutionRequest( - process_id="P16", - dotpath=True, - inputs={ - "scene.colors.bg": "blue", - "scene.colors.opacity": 0.7, - "scene.colors.fg": "white", - "scene.models.path": "models/*", - "log_file": "logs/*", - }, - ) - process_request = request.to_process_request() - self.assertIsInstance(process_request, ProcessRequest) - self.assertEqual( - { - "scene": { - "colors": { - "bg": "blue", - "opacity": 0.7, - "fg": "white", - }, - "models": { - "path": "models/*", - }, - }, - "log_file": "logs/*", - }, - process_request.inputs, - ) - - def test_create_request_from_yaml_stdin(self): - stream = StringIO("process_id: test_func\ninputs:\n x: 7\n y: 9") - with patch("sys.stdin", new=stream): - request = ExecutionRequest.create(request_path="-") - self.assertEqual( - ExecutionRequest(process_id="test_func", inputs={"x": 7, "y": 9}), - request, - ) - - def test_create_request_from_json_stdin(self): - stream = StringIO( - "{\n" - ' "process_id": "test_func_2",\n' - ' "inputs": {\n' - ' "x": 0,\n' - ' "y": -4' - " }\n" - "}" - ) - with patch("sys.stdin", new=stream): - request = ExecutionRequest.create(request_path="-") - self.assertEqual( - ExecutionRequest(process_id="test_func_2", inputs={"x": 0, "y": -4}), - request, - ) - - def test_create_request_from_file(self): - with open(REQUEST_PATH, mode="w") as stream: - stream.write("process_id: test_func\ninputs:\n x: 5\n y: 2\n") - - request = ExecutionRequest.create(request_path=REQUEST_PATH) - self.assertEqual( - ExecutionRequest(process_id="test_func", inputs={"x": 5, "y": 2}), - request, - ) - - def test_create_request_from_with_dotpath_and_nested_inputs(self): - request = ExecutionRequest.create( - process_id="P16", - dotpath=True, - inputs=[ - "scene.colors.bg=blue", - "scene.colors.opacity=0.7", - "scene.colors.fg=white", - "scene.models.path=models/*", - "log_file=logs/*", - ], - ) - # noinspection PyTypeChecker - self.assertEqual( - ExecutionRequest( - process_id="P16", - dotpath=True, - inputs={ - "scene.colors.bg": "blue", - "scene.colors.opacity": 0.7, - "scene.colors.fg": "white", - "scene.models.path": "models/*", - "log_file": "logs/*", - }, - outputs=None, - subscriber=None, - ), - request, - ) - - # noinspection PyPep8Naming - def test_create_request_from_inputs_and_subscribers(self): - successUri = "https://myhost/api/v1/subscriptions/success" - failedUri = "https://myhost/api/v1/subscriptions/failed" - inProgressUri = "https://myhost/api/v1/subscriptions/progress" - request = ExecutionRequest.create( - process_id="test_func", - inputs=[ - "flag", - "x=false", - "y=13.8", - "z=string", - ], - subscribers=[ - f"success={successUri}", - f"failed={failedUri}", - f"progress={inProgressUri}", - ], - ) - # noinspection PyTypeChecker - self.assertEqual( - ExecutionRequest( - process_id="test_func", - inputs={"flag": True, "x": False, "y": 13.8, "z": "string"}, - outputs=None, - subscriber=Subscriber( - successUri=successUri, - failedUri=failedUri, - inProgressUri=inProgressUri, - ), - ), - request, - ) - - def test_create_request_from_file_and_inputs(self): - with open(REQUEST_PATH, mode="w") as stream: - stream.write("process_id: test_func\ninputs:\n x: 5\n y: 2\n") - - request = ExecutionRequest.create(request_path=REQUEST_PATH, inputs=["x=13"]) - self.assertEqual( - ExecutionRequest(process_id="test_func", inputs={"x": 13, "y": 2}), - request, - ) - - # noinspection PyMethodMayBeStatic - def test_create_request_from_nothing(self): - with pytest.raises(click.ClickException, match="Execution request is invalid:"): - ExecutionRequest.create() - - # noinspection PyMethodMayBeStatic - def test_create_request_from_invalid_file(self): - with open(REQUEST_PATH, mode="w") as stream: - stream.write("42\n") - with pytest.raises( - click.ClickException, match="Request must be an object, but was type int" - ): - ExecutionRequest.create(request_path=REQUEST_PATH) - - # noinspection PyMethodMayBeStatic - def test_create_request_from_invalid_input(self): - with pytest.raises(click.ClickException, match="Invalid request NAME: '2x'"): - ExecutionRequest.create(process_id="my_func", inputs=["2x=20'"]) - - # noinspection PyMethodMayBeStatic - def test_create_request_from_invalid_subscription(self): - with pytest.raises( - click.ClickException, - match=( - r"Invalid subscriber item: must have form `EVENT=URL`, " - r"but was 'success\:http\:\/\/localhost\/success'" - ), - ): - ExecutionRequest.create( - process_id="my_func", subscribers=["success:http://localhost/success"] - ) - - with pytest.raises( - click.ClickException, - match=( - r"Invalid subscriber EVENT: must be one of " - r"\[success\|failed\|progress\], but was 'error'" - ), - ): - ExecutionRequest.create( - process_id="my_func", subscribers=["error=http://localhost/error"] - ) - - with pytest.raises( - click.ClickException, - match="Invalid subscriber URL: 'localhorst'", - ): - ExecutionRequest.create( - process_id="my_func", subscribers=["failed=localhorst"] - ) - - -class ExecutionRequestFromProcessDescriptionTest(TestCase): - # noinspection PyArgumentList - cases = [ - [None, {}], - [None, Schema()], - [983, Schema(default=983)], - ["bibo", Schema(default="bibo", type="string")], - [False, Schema(type="boolean")], - [0, Schema(type="integer")], - [0, Schema(type="number")], - ["", Schema(type="string")], - [[], Schema(type="array")], - [{}, Schema(type="object")], - ["bert", Schema(enum=["bert", "ernie"])], - [None, Schema(nullable=True)], - ] - - process_description = ProcessDescription( - id="T13", - version="0", - inputs={ - f"p{i}": InputDescription(schema=schema) - for i, (_, schema) in enumerate(cases) - }, - ) - - def test_all_types(self): - process_description = ProcessDescription( - id="T13", - version="0", - inputs={ - f"p{i}": InputDescription(schema=schema) - for i, (_, schema) in enumerate(self.cases) - }, - ) - self.assertEqual( - ExecutionRequest( - process_id="T13", - inputs={ - f"p{i}": expected_value - for i, (expected_value, _) in enumerate(self.cases) - }, - outputs=None, - ), - ExecutionRequest.from_process_description( - process_description, - ), - ) - - def test_nested(self): - process_description = ProcessDescription( - id="T13", - version="8", - inputs={ - "a": InputDescription( - schema=Schema( - **{ - "type": "object", - "properties": { - "b": Schema(**{"type": "object"}), - "d": Schema(**{"type": "object"}), - }, - } - ), - ), - "f": InputDescription( - schema=Schema(**{"type": "number"}), - ), - }, - ) - self.assertEqual( - ExecutionRequest( - process_id="T13", - dotpath=False, - inputs={"a": {"b": {}, "d": {}}, "f": 0}, - outputs=None, - ), - ExecutionRequest.from_process_description(process_description), - ) - self.assertEqual( - ExecutionRequest( - process_id="T13", - dotpath=False, - inputs={"a": {"b": {}, "d": {}}, "f": 0}, - outputs=None, - ), - ExecutionRequest.from_process_description( - process_description, dotpath=False - ), - ) - - def test_nested_dotpath(self): - process_description = ProcessDescription( - id="T13", - version="8", - inputs={ - "a": InputDescription( - schema=Schema( - **{ - "type": "object", - "properties": { - "b": Schema(**{"type": "object"}), - "d": Schema(**{"type": "array"}), - }, - } - ), - ), - "f": InputDescription( - schema=Schema(**{"type": "number"}), - ), - }, - ) - self.assertEqual( - ExecutionRequest( - process_id="T13", - dotpath=True, - inputs={"a.b": {}, "a.d": [], "f": 0}, - outputs=None, - ), - ExecutionRequest.from_process_description( - process_description, dotpath=True - ), - ) - - def test_no_inputs(self): - self.assertEqual( - ExecutionRequest(process_id="T13", inputs={}, outputs=None), - ExecutionRequest.from_process_description( - ProcessDescription(id="T13", version="0") - ), - ) diff --git a/s2gos-common/src/tests/process/test_schema.py b/s2gos-common/src/tests/process/test_schema.py deleted file mode 100644 index adc8369..0000000 --- a/s2gos-common/src/tests/process/test_schema.py +++ /dev/null @@ -1,109 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from typing import Annotated -from unittest import TestCase - -import pydantic -import pytest - -from s2gos_common.models import Schema -from s2gos_common.process.schema import ( - create_schema_instance, - inline_schema_refs, -) - - -class SchemaTest(TestCase): - def test_pydantic_model_json_schema(self): - class MyModel(pydantic.BaseModel): - x: Annotated[float, pydantic.Field(ge=-1.5, le=1.5)] - y: Annotated[float, pydantic.Field(gt=0.0, lt=1.0)] - - schema = MyModel.model_json_schema() - self.assertEqual( - { - "type": "object", - "title": "MyModel", - "required": ["x", "y"], - "properties": { - "x": { - "maximum": 1.5, - "minimum": -1.5, - "title": "X", - "type": "number", - }, - "y": { - "exclusiveMaximum": 1.0, - "exclusiveMinimum": 0.0, - "title": "Y", - "type": "number", - }, - }, - }, - schema, - ) - - def test_create_schema_instance(self): - self.assertEqual( - Schema(type="number"), - create_schema_instance("x", {"type": "number"}), - ) - - with pytest.raises(pydantic.ValidationError): - create_schema_instance("x", {"tüp": "number"}) - - def test_inline_schema_refs(self): - schema = inline_schema_refs( - { - "type": "array", - "items": {"$ref": "#/$defs/Line"}, - "$defs": { - "Line": { - "type": "object", - "properties": { - "p1": {"$ref": "#/$defs/Point"}, - "p2": {"$ref": "#/$defs/Point"}, - }, - "required": ["p1", "p2"], - }, - "Point": { - "type": "object", - "properties": { - "x": {"type": "number"}, - "y": {"type": "number"}, - }, - "required": ["x", "y"], - }, - }, - } - ) - self.assertEqual( - { - "type": "array", - "items": { - "type": "object", - "required": ["p1", "p2"], - "properties": { - "p1": { - "type": "object", - "required": ["x", "y"], - "properties": { - "x": {"type": "number"}, - "y": {"type": "number"}, - }, - }, - "p2": { - "type": "object", - "required": ["x", "y"], - "properties": { - "x": {"type": "number"}, - "y": {"type": "number"}, - }, - }, - }, - }, - }, - schema, - ) diff --git a/s2gos-common/src/tests/test_models.py b/s2gos-common/src/tests/test_models.py deleted file mode 100644 index 548cc9c..0000000 --- a/s2gos-common/src/tests/test_models.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import inspect -from enum import Enum -from unittest import TestCase - -from pydantic import BaseModel - -import s2gos_common.models as s2g_models - -REQUIRED_ENUMS = { - "CRS", - "DataType", - "MaxOccurs", - "JobControlOptions", - "JobStatus", -} - -REQUIRED_CLASSES = { - "ApiError", - "Capabilities", - "ConformanceDeclaration", - "Format", - "InputDescription", - "JobInfo", - "JobList", - "Link", - "Metadata", - "Output", - "OutputDescription", - "ProcessDescription", - "ProcessList", - "ProcessRequest", - "ProcessSummary", - "Schema", -} - - -class ModelsTest(TestCase): - def test_enums(self): - all_enums = set( - name - for name, obj in inspect.getmembers(s2g_models, inspect.isclass) - if issubclass(obj, Enum) - ) - self.assertSetIsOk(REQUIRED_ENUMS, all_enums) - - def test_classes(self): - all_classes = set( - name - for name, obj in inspect.getmembers(s2g_models, inspect.isclass) - if issubclass(obj, BaseModel) - ) - self.assertSetIsOk(REQUIRED_CLASSES, all_classes) - - def assertSetIsOk(self, required: set[str], actual: set[str]): - contained_items = set(c for c in required if c in actual) - self.assertSetEqual(required, contained_items, "contained") - - def test_models_have_repr_json(self): - for name, obj in inspect.getmembers(s2g_models, inspect.isclass): - if name in REQUIRED_CLASSES and issubclass(obj, BaseModel): - self.assertTrue(hasattr(obj, "_repr_json_"), msg=f"model {name}") - - obj = s2g_models.Bbox(bbox=[10, 20, 30, 40]) - json_repr = obj._repr_json_() - self.assertEqual( - ( - {"bbox": [10.0, 20.0, 30.0, 40.0]}, - {"root": "Bbox object:"}, - ), - json_repr, - ) diff --git a/s2gos-common/src/tests/test_service.py b/s2gos-common/src/tests/test_service.py deleted file mode 100644 index 4cd779f..0000000 --- a/s2gos-common/src/tests/test_service.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import inspect -from unittest import TestCase - -from s2gos_common.service import Service - -REQUIRED_METHODS = { - "dismiss_job", - "execute_process", - "get_capabilities", - "get_conformance", - "get_job_results", - "get_process", - "get_processes", - "get_job", - "get_jobs", -} - - -class ServiceTest(TestCase): - def test_methods(self): - all_method_names = set( - name for name, obj in inspect.getmembers(Service, inspect.isfunction) - ) - self.assertSetEqual(REQUIRED_METHODS, set(all_method_names)) diff --git a/s2gos-common/src/tests/test_testing.py b/s2gos-common/src/tests/test_testing.py deleted file mode 100644 index 02e039a..0000000 --- a/s2gos-common/src/tests/test_testing.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import os -from unittest import TestCase - -import pytest - -from s2gos_common.models import Schema -from s2gos_common.util.testing import BaseModelMixin, set_env_cm - - -class TestingTest(BaseModelMixin, TestCase): - def test_assert_base_model_equal(self): - self.assertBaseModelEqual(Schema(type="integer"), Schema(type="integer")) - with pytest.raises(AssertionError): - self.assertBaseModelEqual(Schema(type="integer"), Schema(type="string")) - - def test_set_env_cm(self): - old_env = dict(os.environ) - with set_env_cm(S2GOS_SERVICE="abc", S2GOS_USER_NAME="xyz"): - self.assertEqual("abc", os.environ.get("S2GOS_SERVICE")) - self.assertEqual("xyz", os.environ.get("S2GOS_USER_NAME")) - self.assertNotEqual(old_env, os.environ) - with set_env_cm(S2GOS_SERVICE=None, S2GOS_USER_NAME=None): - self.assertEqual(None, os.environ.get("S2GOS_SERVICE")) - self.assertEqual(None, os.environ.get("S2GOS_USER_NAME")) - self.assertEqual("abc", os.environ.get("S2GOS_SERVICE")) - self.assertEqual("xyz", os.environ.get("S2GOS_USER_NAME")) - self.assertNotEqual(old_env, os.environ) - self.assertEqual(old_env, os.environ) diff --git a/s2gos-common/src/tests/util/__init__.py b/s2gos-common/src/tests/util/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-common/src/tests/util/cli/__init__.py b/s2gos-common/src/tests/util/cli/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/s2gos-common/src/tests/util/cli/test_group.py b/s2gos-common/src/tests/util/cli/test_group.py deleted file mode 100644 index 123ba40..0000000 --- a/s2gos-common/src/tests/util/cli/test_group.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import unittest - -import click -import pytest - -from s2gos_common.util.cli.group import AliasedGroup - - -class AliasedGroupTest(unittest.TestCase): - def setUp(self): - tca = click.Command("test-command-a") - tcb = click.Command("test-command-b") - tcc1 = click.Command("test-command-c") - tcc2 = click.Command("tiger-claw-command") - self.group = AliasedGroup(name="test-group", commands=[tca, tcb, tcc1, tcc2]) - - def test_get_command_ok(self): - self.assert_alias_ok("test-command-a", "tca") - self.assert_alias_ok("test-command-b", "tcb") - - def test_get_command_fail(self): - ctx = click.Context(self.group) - with pytest.raises(click.UsageError): - self.group.get_command(ctx, "tcc") - self.assertIsNone(self.group.get_command(ctx, "test-command-d")) - self.assertIsNone(self.group.get_command(ctx, "tcd")) - - def assert_alias_ok(self, command_name, command_alias_name): - ctx = click.Context(self.group) - command = self.group.get_command(ctx, command_name) - self.assertIsNotNone(command) - self.assertEqual(command_name, command.name) - alias_command = self.group.get_command(ctx, command_alias_name) - self.assertIsNotNone(alias_command) - self.assertEqual(command_name, alias_command.name) - - def test_resolve_command_ok(self): - ctx = click.Context(self.group) - result = self.group.resolve_command(ctx, ["tcb"]) - self.assertIsInstance(result, tuple) - self.assertEqual(3, len(result)) - self.assertEqual("test-command-b", result[0]) - self.assertIsInstance(result[1], click.Command) - self.assertEqual([], result[2]) - - def test_resolve_command_fail(self): - ctx = click.Context(self.group, resilient_parsing=True) - result = self.group.resolve_command(ctx, ["tcx"]) - self.assertEqual((None, None, []), result) - - ctx = click.Context(self.group, resilient_parsing=False) - with pytest.raises(click.UsageError): - self.group.resolve_command(ctx, ["tcx"]) diff --git a/s2gos-common/src/tests/util/test_dynimp.py b/s2gos-common/src/tests/util/test_dynimp.py deleted file mode 100644 index aded004..0000000 --- a/s2gos-common/src/tests/util/test_dynimp.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import unittest - -import pytest - -from s2gos_common.util.dynimp import import_value - -my_nice_number = 137 -my_nice_string = "137" - - -class ImportAttributeTest(unittest.TestCase): - def test_ok(self): - self.assertEqual( - 137, - import_value( - "tests.util.test_dynimp:my_nice_number", type=int, name="nice number" - ), - ) - - def test_invalid_ref(self): - self.assert_fails( - "hello.num", - r"The nice number reference must be passed in the form " - r"'path\.to\.module\:attr', but got 'hello\.num'\.", - ) - - def test_invalid_module(self): - self.assert_fails( - "hel.lo:num", - r"Cannot import module 'hel.lo'\.", - ) - - def test_invalid_attrib(self): - self.assert_fails( - "tests.util.test_dynimp:num", - r"Module 'tests\.util\.test_dynimp' " - r"has no attribute 'num'\.", - ) - - def test_invalid_type(self): - self.assert_fails( - "tests.util.test_dynimp:my_nice_string", - r"The reference 'tests\.util\.test_dynimp:my_nice_string' " - r"should refer to a nice number of type int, but got type str\.", - exc=TypeError, - ) - - # noinspection PyMethodMayBeStatic - def assert_fails( - self, - value: str | None, - match: str, - exc: type[Exception] = ValueError, - ): - with pytest.raises(exc, match=match): - import_value(value, type=int, name="nice number") diff --git a/s2gos-common/src/tests/util/test_obj.py b/s2gos-common/src/tests/util/test_obj.py deleted file mode 100644 index d2eeab8..0000000 --- a/s2gos-common/src/tests/util/test_obj.py +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import pytest - -# noinspection PyProtectedMember -from s2gos_common.util.obj import _nest_one, flatten_obj, nest_dict, nest_obj - - -def test_flatten_and_nest_dict_1(): - nested = {"a": {"b": {"c": 1}}} - flat = flatten_obj(nested) - assert flat == {"a.b.c": 1} - assert nest_dict(flat) == nested - - -def test_flatten_and_nest_dict_2(): - nested = {"a": {"b": {}, "d": {}}, "f": 0} - flat = flatten_obj(nested) - assert flat == {"a.b": {}, "a.d": {}, "f": 0} - assert nest_dict(flat) == nested - - -def test_flatten_and_nest_dict_only(): - nested = {"a": {"b": {"c": 1}}} - flat = flatten_obj(nested) - assert flat == {"a.b.c": 1} - assert nest_obj(flat) == nested - - -def test_flatten_and_nest_list_only(): - nested = [1, 2, [3, 4]] - flat = flatten_obj(nested, flatten_lists=True) - assert flat == {"0": 1, "1": 2, "2.0": 3, "2.1": 4} - assert nest_obj(flat) == nested - - -def test_flatten_and_nest_mixed(): - nested = {"a": [{"x": 1}, {"y": 2}], "b": 3} - flat = flatten_obj(nested, flatten_lists=True) - assert flat == {"a.0.x": 1, "a.1.y": 2, "b": 3} - assert nest_obj(flat) == nested - - -def test_overwrite_and_sparse_lists(): - flat = {"a.0": "first", "a.2": "third"} - nested = nest_obj(flat) - assert nested == {"a": ["first", None, "third"]} - assert flatten_obj(nested, flatten_lists=True) == flat - - -def test_nest_fail(): - with pytest.raises(TypeError, match="expected key of type str, got int"): - nest_obj({"a.b": 13, "a.0": 14}) - - with pytest.raises(TypeError, match="expected index of type int, got str"): - nest_obj({"a.0": 13, "a.b": 14}) - - with pytest.raises(TypeError, match="expected a list or a dict, got int"): - # noinspection PyTypeChecker - nest_obj({"a.b": 13, "a.c": 14}, root=0) - - -def test_nest_one_into_dict(): - nested = _nest_one({}, "a", 13) - assert nested == {"a": 13} - - nested = _nest_one({}, "a.b", 13) - assert nested == {"a": {"b": 13}} - - nested = _nest_one({}, "a.b.c", 13) - assert nested == {"a": {"b": {"c": 13}}} - - with pytest.raises(TypeError): - _nest_one([], "a.b.c", 13) - - -def test_nest_one_into_list(): - nested = _nest_one([], "0", 13) - assert nested == [13] - - nested = _nest_one([], "0.b", 13) - assert nested == [{"b": 13}] - - nested = _nest_one([], "0.b.c", 13) - assert nested == [{"b": {"c": 13}}] - - with pytest.raises(TypeError): - _nest_one([], "a", 13) - - # nested = nest_one({}, "0.a.b", 13) - # assert nested == [{"a": {"b": 13}}] diff --git a/s2gos-server/pyproject.toml b/s2gos-server/pyproject.toml index 815de06..af74b5a 100644 --- a/s2gos-server/pyproject.toml +++ b/s2gos-server/pyproject.toml @@ -38,14 +38,9 @@ classifiers = [ ] requires-python = ">=3.10" dependencies = [ - "fastapi", - "pydantic", - "pyyaml", - "typer", - "uvicorn", # Eozilla dependencies - "gavicore", - "wraptile", + "gavicore >=0.0.8", + "wraptile >=0.0.8", ] [project.scripts] diff --git a/s2gos-server/src/s2gos_server/cli.py b/s2gos-server/src/s2gos_server/cli.py index 311e92c..aff0662 100644 --- a/s2gos-server/src/s2gos_server/cli.py +++ b/s2gos-server/src/s2gos_server/cli.py @@ -2,11 +2,11 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -from wraptile.cli import get_cli +from wraptile.cli import new_cli from s2gos_server import __version__ as version -cli = get_cli("s2gos-server", version=version) +cli = new_cli(name="s2gos-server", version=version) __all__ = ["cli"] diff --git a/s2gos-server/src/tests/__init__.py b/s2gos-server/src/tests/__init__.py deleted file mode 100644 index 22d05e1..0000000 --- a/s2gos-server/src/tests/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. diff --git a/s2gos-client/src/tests/__init__.py b/s2gos-server/tests/__init__.py similarity index 100% rename from s2gos-client/src/tests/__init__.py rename to s2gos-server/tests/__init__.py diff --git a/s2gos-airflow/tests/__init__.py b/s2gos-server/tests/py.typed similarity index 100% rename from s2gos-airflow/tests/__init__.py rename to s2gos-server/tests/py.typed diff --git a/s2gos-server/src/tests/test_cli.py b/s2gos-server/tests/test_cli.py similarity index 73% rename from s2gos-server/src/tests/test_cli.py rename to s2gos-server/tests/test_cli.py index eb050c8..e0ed2c1 100644 --- a/s2gos-server/src/tests/test_cli.py +++ b/s2gos-server/tests/test_cli.py @@ -2,8 +2,8 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -import s2gos_client.cli +import s2gos_server.cli def test_cli_ok(): - assert {"cli"}.issubset(dir(s2gos_client.cli)) + assert {"cli"}.issubset(dir(s2gos_server.cli)) diff --git a/tools/common.py b/tools/common.py index 15369bd..042c24c 100644 --- a/tools/common.py +++ b/tools/common.py @@ -2,163 +2,8 @@ # Permissions are hereby granted under the terms of the Apache 2.0 License: # https://opensource.org/license/apache-2-0. -import datetime -import re -import subprocess from pathlib import Path -from typing import Any, Final +from typing import Final -from .openapi import OAMethod - -THIS_DIR = Path(__file__).parent.resolve() +THIS_DIR: Final = Path(__file__).parent.resolve() S2GOS_PATH: Final = THIS_DIR.parent -OPEN_API_PATH: Final = THIS_DIR / "openapi.yaml" - -C_TAB: Final = " " -D_TAB: Final = " " - -_REF_PREFIX = "#/components/schemas/" - -_PY_TYPES = { - "null": "None", - "boolean": "bool", - "integer": "int", - "number": "float", - "string": "str", - "array": "list[Any]", - "object": "dict[str, Any]", -} - - -def write_file(generator_name: str, file_path: Path, code_parts: list[str]): - with file_path.open("wt") as stream: - stream.write(f"# generated by {generator_name}:\n") - stream.write(f"# filename: {file_path.name}:\n") - stream.write(f"# timestamp: {datetime.datetime.now().isoformat()}\n") - stream.write("\n") - for code_part in code_parts: - stream.write(code_part) - - print(f"✔ Generated {file_path}") - subprocess.run(["isort", str(file_path)]) - subprocess.run(["ruff", "format", str(file_path)]) - subprocess.run(["ruff", "check", "--fix", str(file_path)]) - - -def parse_responses( - method: OAMethod, models: set[str], skip_errors: bool = False -) -> tuple[dict[str, tuple[str, list[str]]], dict[str, tuple[str, list[str]]]]: - return_types: dict[str, tuple[str, list[str]]] = {} - error_types: dict[str, tuple[str, list[str]]] = {} - if method.responses: - for key, response in method.responses.items(): - status_code = int(key) - description = response.description - desc_lines = description.split("\n") if description else [] - if response.content: - json_content = response.content.get("application/json") - if json_content and json_content.schema_: - if 200 <= status_code < 300: - response_type = to_py_type( - json_content.schema_, "responses", models - ) - return_types[key] = response_type, desc_lines - elif not skip_errors: - response_type = to_py_type( - json_content.schema_, "responses", models - ) - error_types[key] = response_type, desc_lines - return return_types, error_types - - -def to_py_type( - schema: dict[str, Any], - path: str, - models: set[str], - optional: bool = False, # noqa: F821 -) -> str: - # print(path, f"{schema!r}") - ref_uri: str | None = schema.get("$ref") - if ref_uri: - assert ref_uri.startswith(_REF_PREFIX) - component_name = ref_uri[len(_REF_PREFIX) :] - type_name = component_name[0].upper() + component_name[1:] - models.add(type_name) - return type_name - - one_of: list[dict] | None = schema.get("oneOf") - if one_of: - return to_py_union_type( - [to_py_type(s, path + f".oneOf[{i}]", models) for i, s in enumerate(one_of)] - ) - - any_of: list[dict] | None = schema.get("anyOf") - if any_of: - return to_py_union_type( - [to_py_type(s, path + f".anyOf[{i}]", models) for i, s in enumerate(any_of)] - ) - - all_of: list[dict] | None = schema.get("allOf") - if all_of: - for i, s in enumerate(all_of): - if s.get("$ref"): - return to_py_type(s, path + f".allOf[{i}]", models) - for i, s in enumerate(all_of): - if s.get("type"): - return to_py_type(s, path + f".allOf[{i}]", models) - print(f"warn: cannot convert {path}.allOf") - - enum_ = schema.get("enum") - if enum_: - return f"Literal[{', '.join(to_py_literal(v) for v in enum_)}]" - - const = schema.get("const", ...) - if const is not ...: - return f"Literal[{to_py_literal(const)}]" - - json_type = schema.get("type") - if json_type == "array": - items_schema = schema.get("items") - item_type = to_py_type(items_schema, path + ".type", models) - py_type = f"list[{item_type}]" - elif isinstance(json_type, str): - py_type = _PY_TYPES[json_type] - elif isinstance(json_type, (list, tuple)): - py_type = to_py_union_type([_PY_TYPES[t] for t in json_type]) - else: - print(f"warn: cannot convert {path}") - py_type = "Any" - return to_py_union_type([py_type, "None"]) if optional else py_type - - -def camel_to_snake(name: str) -> str: - """ - Convert a camelCase or PascalCase string to snake_case. - Ensures that the output is also a valid identifier in Python, C, or Java. - - Args: - name (str): A valid camelCase or PascalCase identifier. - - Returns: - str: The converted snake_case identifier. - """ - # Add underscore between lowercase-to-uppercase transitions - name = re.sub(r"(?<=[a-z0-9])([A-Z])", r"_\1", name) - # Add underscore between adjacent capitals and followed by lowercase - # (e.g., "HTTPServer" -> "http_server") - name = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1_\2", name) - # Convert to lowercase - snake = name.lower() - # If it starts with a digit, prepend an underscore to - # make it a valid identifier - if snake and snake[0].isdigit(): - snake = "_" + snake - return snake - - -def to_py_literal(value) -> str: - return repr(value) - - -def to_py_union_type(py_types: list[str]) -> str: - return " | ".join(py_types) diff --git a/tools/gen_client.py b/tools/gen_client.py deleted file mode 100644 index 2ce6671..0000000 --- a/tools/gen_client.py +++ /dev/null @@ -1,337 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import textwrap -from pathlib import Path -from typing import Literal - -from tools.common import ( - C_TAB, - D_TAB, - OPEN_API_PATH, - S2GOS_PATH, - camel_to_snake, - parse_responses, - to_py_type, - write_file, -) -from tools.openapi import OAMethod, OASchema, load_openapi_schema - -GENERATOR_NAME = str(Path(__file__).name) - -SYNC_CLIENT_PATH = S2GOS_PATH / "s2gos-client/src/s2gos_client/api/client.py" -ASYNC_CLIENT_PATH = S2GOS_PATH / "s2gos-client/src/s2gos_client/api/async_client.py" - - -code_header = """ - -from typing import Any, Optional - -from s2gos_common.models import {{ model_imports }} - -from .config import ClientConfig -from .async_client_mixin import AsyncClientMixin -from .client_mixin import ClientMixin -from .ishell import has_ishell as _ # noqa F401 -from .transport import {{ uc_async }}Transport, TransportArgs -from .transport.httpx import HttpxTransport - - -class {{ uc_async }}Client({{ uc_async }}ClientMixin): - \"\"\" - The client API for the web service ({{ hr_async }} mode). - - Args: - config: Optional client configuration object. If given, - other configuration arguments are ignored. - config_path: Optional path of the configuration file to be loaded - server_url: Optional server URL - user_name: Optional username - access_token: Optional private access token - \"\"\" - - def __init__( - self, - *, - config: Optional[ClientConfig] = None, - config_path: Optional[str] = None, - server_url: Optional[str] = None, - user_name: Optional[str] = None, - access_token: Optional[str] = None, - _debug: bool = False, - _transport: Optional[{{ uc_async }}Transport] = None, - ): - self._config = ClientConfig.create( - config=config, - config_path=config_path, - server_url=server_url, - user_name=user_name, - access_token=access_token, - ) - assert self._config.server_url is not None - self._transport = ( - HttpxTransport( - server_url=self._config.server_url, - debug=_debug, - ) - if _transport is None - else _transport - ) - - @property - def config(self) -> ClientConfig: - return self._config - - def _repr_json_(self): - # noinspection PyProtectedMember - return self.config._repr_json_() - -{{ client_methods }} -""" - - -def main(): - schema = load_openapi_schema(OPEN_API_PATH) - - models: set[str] = set() - client_methods = generate_api_code(schema, models, is_async=False) - model_list = ", ".join(sorted(models)) - - sync_code = code_header - sync_code = sync_code.replace("{{ model_imports }}", model_list) - sync_code = sync_code.replace("{{ client_methods }}", client_methods) - sync_code = sync_code.replace("{{ uc_async }}", "") - sync_code = sync_code.replace("{{ hr_async }}", "synchronous") - - write_file( - GENERATOR_NAME, - SYNC_CLIENT_PATH, - [sync_code], - ) - - models: set[str] = set() - client_methods = generate_api_code(schema, models, is_async=True) - model_list = ", ".join(sorted(models)) - - async_code = code_header - async_code = async_code.replace("{{ model_imports }}", model_list) - async_code = async_code.replace("{{ client_methods }}", client_methods) - async_code = async_code.replace("{{ uc_async }}", "Async") - async_code = async_code.replace("{{ hr_async }}", "asynchronous") - - write_file( - GENERATOR_NAME, - ASYNC_CLIENT_PATH, - [async_code], - ) - - -def generate_api_code(schema: OASchema, models: set[str], is_async: bool) -> str: - functions: list[str] = [] - for path, endpoint in schema.paths.items(): - for method_name, method in endpoint.items(): - # noinspection PyTypeChecker - function_code = generate_function_code( - path, method_name, method, models, is_async=is_async - ) - functions.append(function_code) - functions.append(generate_close_method_code(is_async)) - return "\n\n".join(functions) - - -def generate_function_code( - path: str, - method_name: Literal["get", "post", "put", "delete"], - method: OAMethod, - models: set[str], - is_async: bool, -) -> str: - param_args: list[str] = ["self"] - param_kwargs: list[str] = [] - path_param_mappings: list[str] = [] - query_param_mappings: list[str] = [] - for parameter in method.parameters: - param_name = camel_to_snake(parameter.name) - param_type = "Any" - param_default: str | None = None - if parameter.schema_: - param_type = to_py_type( - parameter.schema_, - f"{method.operationId}.{parameter.name}", - models, - ) - default_value = parameter.schema_.get("default", ...) - if default_value is not ...: - param_default = repr(default_value) - if param_default is None: - param_args.append(f"{param_name}: {param_type}") - else: - param_kwargs.append(f"{param_name}: {param_type} = {param_default}") - if parameter.in_ == "path": - path_param_mappings.append(f"{parameter.name!r}: {param_name}") - elif parameter.in_ == "query": - query_param_mappings.append(f"{parameter.name!r}: {param_name}") - else: - print( - f"⚠️ Error: parameter {parameter.name!r}" - f" in {parameter.in_!r} not supported" - ) - - request_type: str | None = None - if method.requestBody: - request_type = "Any" - json_content = method.requestBody.content.get("application/json") - if json_content and json_content.schema_: - request_type = to_py_type( - json_content.schema_, f"{method.operationId}.requestBody", models - ) - if method.requestBody.required: - param_args.append(f"request: {request_type}") - else: - param_kwargs.append(f"request: Optional[{request_type}] = None") - - param_list = ", ".join([*param_args, *param_kwargs, "**kwargs: Any"]) - path_param_dict = "{" + ", ".join(path_param_mappings) + "}" - query_param_dict = "{" + ", ".join(query_param_mappings) + "}" - - return_types, error_types = parse_responses(method, models) - - if not return_types: - return_types = {"200": "None"} - - function_doc = generate_function_doc(method) - return_type_union = " | ".join(set(v[0] for v in return_types.values())) - return_type_dict = ( - "{" + ", ".join([f"{k!r}: {v[0]}" for k, v in return_types.items()]) + "}" - ) - error_type_dict = ( - "{" + ", ".join([f"{k!r}: {v[0]}" for k, v in error_types.items()]) + "}" - ) - - transport_args = [ - f"path={path!r}", - f"method={method_name!r}", - f"path_params={path_param_dict}" if path_param_mappings else None, - f"query_params={query_param_dict}" if query_param_mappings else None, - "request=request" if request_type else None, - f"return_types={return_type_dict}" if return_types else None, - f"error_types={error_type_dict}" if error_types else None, - "extra_kwargs=kwargs", - ] - transport_args_list = ", ".join(a for a in transport_args if a is not None) - - return ( - f"{C_TAB}{'async ' if is_async else ''}" - f"def {camel_to_snake(method.operationId)}({param_list})" - f" -> {return_type_union}:\n" - f"{function_doc}" - f"{C_TAB}{C_TAB}return " - f"{'await ' if is_async else ''}" - f"self._transport.{'async_' if is_async else ''}call(" - f"TransportArgs({transport_args_list})" - f")\n" - ) - - -def generate_close_method_code(is_async: bool) -> str: - if is_async: - return ( - f"{C_TAB}async def close(self):\n" - f'{C_TAB}{C_TAB}"""Close this client."""\n' - f"{C_TAB}{C_TAB}if self._transport is not None:" - f"{C_TAB}{C_TAB}{C_TAB}await self._transport.async_close()" - ) - else: - return ( - f"{C_TAB}def close(self):\n" - f'{C_TAB}{C_TAB}"""Close this client."""\n' - f"{C_TAB}{C_TAB}if self._transport is not None:" - f"{C_TAB}{C_TAB}{C_TAB}self._transport.close()" - ) - - -def generate_function_doc(method: OAMethod) -> str: - doc_lines = method.description.split("\n") if method.description else [] - - if method.parameters: - if doc_lines and doc_lines[-1] != "": - doc_lines.append("") - doc_lines.append("Args:") - for parameter in method.parameters: - param_name = camel_to_snake(parameter.name) - if parameter.description: - param_desc_lines = parameter.description.split("\n") - doc_lines.append(f"{D_TAB}{param_name}: {param_desc_lines[0]}") - doc_lines.extend( - [f"{2 * D_TAB}{line}" for line in param_desc_lines[1:]] - ) - else: - doc_lines.append(f"{D_TAB}{param_name}:") - doc_lines.append(f"{D_TAB}kwargs: Optional keyword arguments that may be") - doc_lines.append(f"{D_TAB}{D_TAB}used by the underlying transport.") - - if method.requestBody: - json_content = method.requestBody.content.get("application/json") - if json_content: - if method.requestBody.description: - param_desc_lines = method.requestBody.description.split("\n") - doc_lines.append(f"{D_TAB}request: {param_desc_lines[0]}") - doc_lines.extend( - [f"{D_TAB}{D_TAB}{line}" for line in param_desc_lines[1:]] - ) - else: - doc_lines.append(" request:") - - return_types, error_types = parse_responses(method, set()) - - def append_return_types( - resp_types: dict[str, tuple[str, list[str]]], lines: list[str] - ): - lines.append("") - lines.append("Returns:") - for resp_code, (resp_type, desc_lines) in resp_types.items(): - if desc_lines: - lines.append(f"{D_TAB}{resp_type}: {desc_lines[0]}") - for desc_line in desc_lines[1:]: - lines.append(f"{D_TAB}{D_TAB}{desc_line}") - else: - lines.append(f"{D_TAB}{resp_type}:") - - def append_error_types( - resp_types: dict[str, tuple[str, list[str]]], lines: list[str] - ): - lines.append("") - lines.append("Raises:") - lines.append(f"{D_TAB}ClientError: If the call to the web service fails") - lines.append(f"{D_TAB}{D_TAB}with a status code != `2xx`.") - if resp_types: - lines.append("") - for resp_code, (resp_type, desc_lines) in resp_types.items(): - if desc_lines: - lines.append(f"{D_TAB}{D_TAB}- `{resp_code}`: {desc_lines[0]}") - for desc_line in desc_lines[1:]: - lines.append(f"{D_TAB}{D_TAB} {desc_line}") - else: - lines.append(f"{D_TAB}{D_TAB}- `{resp_code}`:") - - if return_types: - append_return_types(return_types, doc_lines) - - append_error_types(error_types, doc_lines) - - wrapped_doc_lines = [] - for line in doc_lines: - if line and not line.startswith("|"): - for subline in textwrap.wrap(line, 72): - # TODO: prefix `subline` 1..N with leading whitespaces from `line` - wrapped_doc_lines.append(subline) - else: - wrapped_doc_lines.append(line) - doc_lines = ['"""', *wrapped_doc_lines, '"""'] - doc_lines = [f"{2 * C_TAB}{line}" for line in doc_lines] - return "\n".join(doc_lines) + "\n" - - -if __name__ == "__main__": - main() diff --git a/tools/gen_dags.py b/tools/gen_dags.py deleted file mode 100644 index eaf9f0b..0000000 --- a/tools/gen_dags.py +++ /dev/null @@ -1,108 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import importlib -from pathlib import Path -from typing import Any - -import typer - -from s2gos_common.process import Process -from s2gos_server.services.local import LocalService -from tools.common import S2GOS_PATH, write_file - -GENERATOR_NAME = str(Path(__file__).name) - -SERVICE_SPEC = "s2gos_server.services.local.testing:service" -DAGS_FOLDER = S2GOS_PATH / "s2gos-airflow/dags" - - -def main(service_spec: str = SERVICE_SPEC, dags_folder: Path = DAGS_FOLDER): - service = load_service(service_spec) - dags_folder.mkdir(exist_ok=True) - for process_id, process in service.process_registry.items(): - write_file( - GENERATOR_NAME, - dags_folder / f"{process_id}.py", - [gen_dag(process)], - ) - - -def gen_dag(process: Process) -> str: - process_description = process.description - function_name = process_description.id - input_descriptions = process_description.inputs - - param_specs = [ - f"{param_name!r}: Param({get_param_args(input_description)})" - for param_name, input_description in input_descriptions.items() - ] - - tab = " " - num_outputs = len(process_description.outputs or []) - # noinspection PyUnresolvedReferences - function_module = process.function.__module__ - lines = [ - "from airflow.sdk import Param, dag, task", - "", - f"from {function_module} import {function_name}", - "", - "", - "@dag(", - f"{tab}{function_name!r},", - f"{tab}dag_display_name={process.description.title!r},", - f"{tab}description={process_description.description!r},", - f"{tab}params=" + "{", - *[f"{tab}{tab}{p}," for p in param_specs], - f"{tab}" + "},", - f"{tab}is_paused_upon_creation=False,", - ")", - f"def {function_name}_dag():", - "", - f"{tab}@task(multiple_outputs={(num_outputs > 1)!r})", - f"{tab}def {function_name}_task(params):", - f"{tab}{tab}return {function_name}(**params)", - "", - f"{tab}task_instance = {function_name}_task() # noqa: F841", - "", - f"{function_name}_dag()", - ] - return "\n".join(lines) + "\n" - - -def get_param_args(input_description): - schema = dict( - input_description.schema_.model_dump( - mode="json", - by_alias=True, - exclude_defaults=True, - exclude_none=True, - exclude_unset=True, - ) - ) - param_args: list[tuple[str, Any]] = [] - if "default" in schema: - param_args.append(("default", schema.pop("default"))) - if "type" in schema: - param_args.append(("type", schema.pop("type"))) - if input_description.title: - schema.pop("title", None) - param_args.append(("title", input_description.title)) - if input_description.description: - schema.pop("description", None) - param_args.append(("description", input_description.description)) - param_args.extend(sorted(schema.items(), key=lambda item: item[0])) - return ", ".join(f"{sk}={sv!r}" for sk, sv in param_args) - - -def load_service(service_spec: str) -> LocalService: - module_name, attr_name = service_spec.rsplit(":", maxsplit=1) - module = importlib.import_module(module_name) - service = getattr(module, attr_name) - assert isinstance(service, LocalService) - return service - - -if __name__ == "__main__": - typer.run(main) diff --git a/tools/gen_models.py b/tools/gen_models.py deleted file mode 100644 index a00446f..0000000 --- a/tools/gen_models.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -import datamodel_code_generator as dcg - -from tools.common import OPEN_API_PATH, S2GOS_PATH - -MODELS_PATH = S2GOS_PATH / "s2gos-common/src/s2gos_common/models.py" - - -def main(): - assert not bool(dcg), ( - "NO ERROR: see s2gos_common.models.QualifiedValue, then uncomment" - ) - dcg.generate( - input_=OPEN_API_PATH, - input_file_type=dcg.InputFileType.OpenAPI, - # use_annotated=True, # --> if True, mypy cannot see pydantic aliases - use_double_quotes=True, - use_standard_collections=True, - use_schema_description=True, - use_non_positive_negative_number_constrained_types=True, - use_title_as_name=True, - use_one_literal_as_default=True, - use_union_operator=False, - field_constraints=True, - set_default_enum_member=True, - keep_model_order=False, - target_python_version=dcg.PythonVersion.PY_310, - output_model_type=dcg.DataModelType.PydanticV2BaseModel, - output=MODELS_PATH, - ) - - -if __name__ == "__main__": - main() diff --git a/tools/gen_server.py b/tools/gen_server.py deleted file mode 100644 index ac48348..0000000 --- a/tools/gen_server.py +++ /dev/null @@ -1,203 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. -import re -from pathlib import Path -from typing import Literal - -from tools.common import ( - C_TAB, - OPEN_API_PATH, - S2GOS_PATH, - camel_to_snake, - parse_responses, - to_py_type, - write_file, -) -from tools.openapi import OAMethod, OASchema, load_openapi_schema - -GENERATOR_NAME = str(Path(__file__).name) - -ROUTES_PATH = S2GOS_PATH / "s2gos-server/src/s2gos_server/routes.py" -SERVICE_PATH = S2GOS_PATH / "s2gos-common/src/s2gos_common/service.py" - -magic_param_list = [ - ("request", "fastapi.Request"), - ("response", "fastapi.Response"), - # add more as desired -] - - -def main(): - schema = load_openapi_schema(OPEN_API_PATH) - models: set[str] = set() - routes_code, service_code = generate_code_for_paths(schema, models) - model_list = ", ".join(sorted(models)) - - write_file( - GENERATOR_NAME, - ROUTES_PATH, - [ - "import fastapi\n", - "\n", - f"from s2gos_common.models import {model_list}\n", - "from s2gos_common.service import Service\n", - "from .app import app\n", - "from .provider import get_service\n", - "\n", - routes_code, - ], - ) - - write_file( - GENERATOR_NAME, - SERVICE_PATH, - [ - "from abc import ABC, abstractmethod\n", - "\n", - f"from .models import {model_list}\n", - "\n", - "class Service(ABC):\n", - service_code, - ], - ) - - -def generate_code_for_paths(schema: OASchema, models: set[str]) -> tuple[str, str]: - route_functions: list[str] = [] - service_methods: list[str] = [] - for path, endpoint in schema.paths.items(): - for method_name, method in endpoint.items(): - # noinspection PyTypeChecker - route_function, service_method = generate_method_code( - path, method_name, method, models - ) - route_functions.append(route_function) - service_methods.append(service_method) - return "\n\n".join(route_functions), "\n\n".join(service_methods) - - -def generate_method_code( - path: str, - method_name: Literal["get", "post", "put", "delete"], - method: OAMethod, - models: set[str], -) -> tuple[str, str]: - pos_params: list[str] = [] - kwargs_params: list[str] = [] - pos_service_params: list[str] = [] - args_service_params: list[str] = [] - kwargs_service_params: list[str] = [] - service_args: list[str] = [] - service_kwargs: list[str] = [] - for parameter in method.parameters: - param_name = camel_to_snake(parameter.name) - param_type = "Any" - param_default: str | None = None - if parameter.schema_: - param_type = to_py_type( - parameter.schema_, - f"{method.operationId}.{parameter.name}", - models, - ) - default_value = parameter.schema_.get("default", ...) - if default_value is not ...: - param_default = repr(default_value) - if param_default is None: - pos_params.append(f"{parameter.name}: {param_type}") - pos_service_params.append(f"{param_name}: {param_type}") - service_args.append(f"{param_name}={parameter.name}") - else: - kwargs_params.append(f"{parameter.name}: {param_type} = {param_default}") - args_service_params.append(f"{param_name}: {param_type}") - service_kwargs.append(f"{param_name}={parameter.name}") - - if method.requestBody: - request_type = "Any" - json_content = method.requestBody.content.get("application/json") - if json_content and json_content.schema_: - request_type = to_py_type( - json_content.schema_, f"{method.operationId}.requestBody", models - ) - request_param_name = _camel_to_snake(request_type) - if method.requestBody.required: - request_pos_param = f"{request_param_name}: {request_type}" - pos_params.append(request_pos_param) - pos_service_params.append(request_pos_param) - else: - request_kw_param = f"{request_param_name}: Optional[{request_type}] = None" - kwargs_params.append(request_kw_param) - kwargs_service_params.append(request_kw_param) - service_args.append(f"{request_param_name}={request_param_name}") - - extra_status_code = "" - if method.responses.get("201"): - extra_status_code = ", status_code=201" - - param_list = ", ".join( - [ - *pos_params, - *[f"{k}: {v}" for k, v in magic_param_list], - "service: Service = fastapi.Depends(get_service)", - *kwargs_params, - ] - ) - service_param_list = ", ".join( - [ - "self", - *pos_service_params, - *args_service_params, - "*args", - *kwargs_service_params, - "**kwargs", - ] - ) - param_service_list = ", ".join( - [ - *service_args, - *[f"{k}={k}" for k, _ in magic_param_list], - *service_kwargs, - ] - ) - - return_types_, error_types = parse_responses(method, models, skip_errors=True) - - return_types = list(v[0] for v in return_types_.values()) - if not return_types: - return_types = ["None"] - return_types = sorted(return_types) - - return_type_union = " | ".join(set(return_types)) - py_op_name = camel_to_snake(method.operationId) - method_doc = ( - method.description - or (method.summary and method.summary.capitalize()) - or "No description provided." - ) - return ( - ( - f"# noinspection PyPep8Naming\n" - f"@app.{method_name}({path!r}{extra_status_code})\n" - f"async def {py_op_name}({param_list}):\n" - f"{C_TAB}return await service." - f"{py_op_name}({param_service_list})\n" - ), - ( - f"{C_TAB}@abstractmethod\n" - f"{C_TAB}async def {py_op_name}({service_param_list})" - f" -> {return_type_union}:\n" - f'{C_TAB}{C_TAB}"""{method_doc}"""\n' - ), - ) - - -def _camel_to_snake(name: str) -> str: - """Convert CamelCase or camelCase to snake_case.""" - # Insert underscore before uppercase letters (except at the beginning), then lowercase everything - s1 = re.sub(r"(.)([A-Z][a-z]+)", r"\1_\2", name) - s2 = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", s1) - return s2.lower() - - -if __name__ == "__main__": - main() diff --git a/tools/openapi.py b/tools/openapi.py deleted file mode 100644 index e837c0e..0000000 --- a/tools/openapi.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (c) 2025 by ESA DTE-S2GOS team and contributors -# Permissions are hereby granted under the terms of the Apache 2.0 License: -# https://opensource.org/license/apache-2-0. - -from pathlib import Path -from typing import Annotated, Any, Literal - -import yaml -from pydantic import BaseModel, Field - - -class OAParameter(BaseModel): - name: str - in_: Annotated[ - Literal["path", "query", "header", "cookie"], Field(default=None, alias="in") - ] - description: Annotated[str, Field(default=None)] - required: bool = False - schema_: Annotated[dict[str, Any], Field(default=None, alias="schema")] - - -class OAContent(BaseModel): - schema_: Annotated[dict[str, Any], Field(default=None, alias="schema")] - examples: Annotated[dict[str, Any], Field(default=None)] - - -class OARequestBody(BaseModel): - description: Annotated[str, Field(default=None)] - content: dict[str, OAContent] - required: Annotated[bool, Field(default=False)] - - -class OAResponse(BaseModel): - description: Annotated[str, Field(default=None)] - content: Annotated[dict[str, OAContent], Field(default_factory=lambda: {})] - - -class OAMethod(BaseModel): - tags: Annotated[list[str], Field(default=None)] - summary: Annotated[str, Field(default=None)] - description: Annotated[str, Field(default=None)] - operationId: Annotated[str, Field(default=None)] - parameters: Annotated[list[OAParameter], Field(default_factory=lambda: [])] - requestBody: Annotated[OARequestBody, Field(default=None)] - responses: Annotated[dict[str, OAResponse], Field(default_factory=lambda: {})] - callbacks: Annotated[ - dict[str, dict[str, "OAEndpoint"]], Field(default_factory=lambda: {}) - ] - - -class OAEndpoint(BaseModel): - options: Annotated[OAMethod, Field(default=None)] - get: Annotated[OAMethod, Field(default=None)] - put: Annotated[OAMethod, Field(default=None)] - post: Annotated[OAMethod, Field(default=None)] - delete: Annotated[OAMethod, Field(default=None)] - - -class OASchema(BaseModel): - openapi: str - info: Annotated[dict[str, Any], Field(default_factory=lambda: {})] - servers: Annotated[list[dict[str, Any]], Field(default_factory=lambda: [])] - paths: Annotated[dict[str, dict[str, OAMethod]], Field(default_factory=lambda: {})] - components: Annotated[dict[str, Any], Field(default_factory=lambda: {})] - - -OAMethod.model_rebuild() - - -def load_openapi_schema(schema_path: Path) -> OASchema: - with schema_path.open("rt") as stream: - schema_dict = yaml.load(stream, Loader=yaml.SafeLoader) - return OASchema.model_validate(schema_dict) diff --git a/tools/openapi.yaml b/tools/openapi.yaml deleted file mode 100644 index f550fdb..0000000 --- a/tools/openapi.yaml +++ /dev/null @@ -1,922 +0,0 @@ -openapi: 3.0.3 -info: - title: "S2GOS web API" - description: "S2GOS API conforming to version 1.0.0 of the [OGC API - Processes - Part 1: Core](https://docs.ogc.org/is/18-062r2/18-062r2.html) Standard.\n\n Copyright (c) 2021 Open Geospatial Consortium.\n\n To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ \n\n This document is an API definition document provided alongside the OGC API - Processes standard. The OGC API - Processes Standard specifies a processing interface to communicate over a RESTful protocol using JavaScript Object Notation (JSON) encodings. The specification allows for the wrapping of computational tasks into executable processes that can be offered by a server and be invoked by a client application." - contact: - name: S2GOS development team - url: https://s2gos-dev.github.io - # email: s2gos-team@eradiate.eu - license: - name: Apache 2.0 license - url: http://www.apache.org/licenses/LICENSE-2.0 - version: 1.0.0 -servers: -- url: http://localhost:8008 - description: Local S2GOS demo server -paths: - /: - get: - tags: - - Capabilities - summary: landing page of this API - description: |- - The landing page provides links to the: - * The OpenAPI-definition (no fixed path), - * The Conformance statements (path /conformance), - * The processes metadata (path /processes), - * The endpoint for job monitoring (path /jobs). - - For more information, see [OGC API — Processes — Part 1 Section 7.2](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_landing_page). - operationId: getCapabilities - responses: - "200": - description: |- - The landing page provides links to the API definition - (link relations `service-desc` and `service-doc`), - the Conformance declaration (path `/conformance`, - link relation `http://www.opengis.net/def/rel/ogc/1.0/conformance`), - and to other resources. - content: - application/json: - schema: - $ref: '#/components/schemas/Capabilities' - text/html: - schema: - type: string - "500": - description: A server error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string - /conformance: - get: - tags: - - ConformanceDeclaration - summary: information about standards that this API conforms to - description: | - A list of all conformance classes, specified in a standard, that the server conforms to. - - | Conformance class | URI | - |-----------|-------| - |Core|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/core| - |OGC Process Description|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/ogc-process-description| - |JSON|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/json| - |HTML|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/html| - |OpenAPI Specification 3.0|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/oas30| - |Job list|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/job-list| - |Callback|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/callback| - |Dismiss|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/dismiss| - - For more information, see [OGC API — Processes — Part 1 Section 7.4](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_conformance_classes). - operationId: getConformance - responses: - "200": - description: | - The URIs of all conformance classes supported - by the server. To support "generic" clients that want - to access multiple OGC API - Processes implementations - and - not "just" a specific API / server, the server declares - the conformance classes it implements and conforms to. - content: - application/json: - schema: - $ref: '#/components/schemas/ConformanceDeclaration' - example: - conformsTo: - - http://www.opengis.net/spec/ogcapi-processes/1.0/conf/core - text/html: - schema: - type: string - "500": - description: A server error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string - /processes: - get: - tags: - - ProcessList - summary: retrieve the list of available processes - description: | - The list of processes contains a summary of each process the OGC API - Processes offers, including the link to a more detailed description of the process. - - For more information, see [OGC API — Processes — Part 1 Section 7.9](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_process_list). - operationId: getProcesses - responses: - "200": - description: Information about the available processes - content: - application/json: - schema: - $ref: '#/components/schemas/ProcessList' - /processes/{processID}: - get: - tags: - - ProcessDescription - summary: retrieve a process description - description: | - The process description contains information about inputs and outputs and a link to the execution-endpoint for the process. The Core does not mandate the use of a specific process description to specify the interface of a process. That said, the Core requirements class makes the following recommendation: - - Implementations **should** consider supporting the OGC process description. - - For more information, see [OGC API — Processes — Part 1 Section 7.10](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_process_description). - operationId: getProcess - parameters: - - name: processID - in: path - required: true - schema: - type: string - responses: - "200": - description: A process description. - content: - application/json: - schema: - $ref: '#/components/schemas/ProcessDescription' - examples: - description: - summary: A Process Description example - externalValue: ../../examples/json/ProcessDescription.json - "404": - description: The requested URI was not found. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string - /processes/{processID}/execution: - post: - tags: - - ProcessRequest - - InlineValue - - JobInfo - summary: execute a process. - description: | - Create a new job. - - For more information, see [OGC API — Processes — Part 1 Section 7.11](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_create_job). - operationId: executeProcess - parameters: - - name: processID - in: path - required: true - schema: - type: string - requestBody: - description: Mandatory request JSON - content: - application/json: - schema: - $ref: '#/components/schemas/ProcessRequest' - required: true - responses: - "200": - description: Result of synchronous execution - content: - /*: - schema: - $ref: '#/components/schemas/InlineValue' - "201": - description: Started asynchronous execution. Created job. - headers: - Location: - description: URL to check the status of the execution/job. - schema: - type: string - Preference-Applied: - description: The preference applied to execute the process asynchronously (see. RFC 2740). - schema: - type: string - content: - application/json: - schema: - $ref: '#/components/schemas/JobInfo' - "404": - description: The requested URI was not found. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string - "500": - description: A server error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string - callbacks: - jobCompleted: - '{$request.body#/subscriber/successUri}': - post: - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/JobResults' - responses: - "200": - description: Results received successfully - /jobs: - get: - tags: - - JobList - summary: retrieve the list of jobs. - description: | - List available jobs. - - For more information, see [OGC API — Processes — Part 1 Section 11](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_job_list). - operationId: getJobs - responses: - "200": - description: A list of jobs for this process. - content: - application/json: - schema: - $ref: '#/components/schemas/JobList' - "404": - description: The requested URI was not found. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string - /jobs/{jobId}: - get: - tags: - - JobStatus - summary: retrieve the status of a job - description: | - Show the status of a job. - - For more information, see [OGC API — Processes — Part 1 Section 7.12](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_retrieve_status_info). - operationId: getJob - parameters: - - name: jobId - in: path - description: Local identifier of a job - required: true - schema: - type: string - responses: - "200": - description: The status of a job. - content: - application/json: - schema: - $ref: '#/components/schemas/JobInfo' - "404": - description: The requested URI was not found. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string - "500": - description: A server error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string - delete: - tags: - - Dismiss - summary: "cancel a job execution, remove a finished job" - description: | - Cancel a job execution and removes it from the jobs list. - - For more information, see [OGC API — Processes — Part 1 Section 13](https://docs.ogc.org/is/18-062r2/18-062r2.html#Dismiss). - operationId: dismissJob - parameters: - - name: jobId - in: path - description: Local identifier of a job - required: true - schema: - type: string - responses: - "200": - description: Information about the job. - content: - application/json: - schema: - $ref: '#/components/schemas/JobInfo' - "404": - description: The requested URI was not found. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string - "500": - description: A server error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string - /jobs/{jobId}/results: - get: - tags: - - JobResults - summary: retrieve the result(s) of a job - description: | - List available results of a job. In case of a failure, list errors instead. - - For more information, see [OGC API — Processes — Part 1 Section 7.13](https://docs.ogc.org/is/18-062r2/18-062r2.html#sc_retrieve_job_results). - operationId: getJobResults - parameters: - - name: jobId - in: path - description: Local identifier of a job - required: true - schema: - type: string - responses: - "200": - description: The results of a job. - content: - application/json: - schema: - $ref: '#/components/schemas/JobResults' - "404": - description: The requested URI was not found. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string - "500": - description: A server error occurred. - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - text/html: - schema: - type: string -components: - schemas: - #------------------------------------------------------ - # Generic low-level objects - #------------------------------------------------------ - CRS: - type: string - format: uri - default: http://www.opengis.net/def/crs/OGC/1.3/CRS84 - enum: - - http://www.opengis.net/def/crs/OGC/1.3/CRS84 - - http://www.opengis.net/def/crs/OGC/0/CRS84h - ApiError: - required: - - type - type: object - properties: - type: - type: string - title: - type: string - status: - type: integer - detail: - type: string - instance: - type: string - # Extension of OGC API / Processes core v1 - traceback: - type: array - items: - type: string - additionalProperties: true - description: API error based on RFC 7807 - MaxOccurs: - type: string - enum: - - unbounded - InlineValue: - oneOf: - - nullable: true - - type: boolean - - type: string - format: binary - - type: string - format: uri - - type: string - format: date - - type: string - format: date-time - - type: string - - type: integer - - type: number - - type: array - - type: object - - $ref: '#/components/schemas/Bbox' - Format: - type: object - properties: - mediaType: - type: string - encoding: - type: string - schema: - oneOf: - - type: string - format: uri - - $ref: '#/components/schemas/Schema' - Link: - required: - - href - type: object - properties: - href: - type: string - rel: - type: string - example: service - type: - type: string - example: application/json - hreflang: - type: string - example: en - title: - type: string - QualifiedValue: - allOf: - - $ref: '#/components/schemas/Format' - - type: object - required: - - value - properties: - value: - $ref: '#/components/schemas/InlineValue' - InlineOrRefValue: - oneOf: - - $ref: '#/components/schemas/InlineValue' - - $ref: '#/components/schemas/QualifiedValue' - - $ref: '#/components/schemas/Link' - Bbox: - type: object - required: - - bbox - properties: - bbox: - type: array - minItems: 4 - maxItems: 4 - items: - type: number - crs: - $ref: '#/components/schemas/CRS' - DescriptionType: - type: object - properties: - title: - type: string - description: - type: string - keywords: - type: array - items: - type: string - metadata: - type: array - items: - $ref: '#/components/schemas/Metadata' - additionalParameters: - allOf: - - $ref: '#/components/schemas/Metadata' - - type: object - properties: - parameters: - type: array - items: - $ref: '#/components/schemas/AdditionalParameter' - DataType: - type: string - enum: - - array - - boolean - - integer - - number - - object - - string - Schema: - type: object - properties: - $ref: - type: string - format: uri-reference - title: - type: string - multipleOf: - minimum: 0 - exclusiveMinimum: true - type: number - maximum: - type: number - exclusiveMaximum: - type: boolean - default: false - minimum: - type: number - exclusiveMinimum: - type: boolean - default: false - maxLength: - minimum: 0 - type: integer - minLength: - minimum: 0 - type: integer - default: 0 - pattern: - type: string - format: regex - maxItems: - minimum: 0 - type: integer - minItems: - minimum: 0 - type: integer - default: 0 - uniqueItems: - type: boolean - default: false - maxProperties: - minimum: 0 - type: integer - minProperties: - minimum: 0 - type: integer - default: 0 - required: - minItems: 1 - uniqueItems: true - type: array - items: - type: string - enum: - minItems: 1 - uniqueItems: false - type: array - type: - $ref: '#/components/schemas/DataType' - not: - $ref: '#/components/schemas/Schema' - allOf: - type: array - items: - $ref: '#/components/schemas/Schema' - oneOf: - type: array - items: - $ref: '#/components/schemas/Schema' - anyOf: - type: array - items: - $ref: '#/components/schemas/Schema' - discriminator: - type: object - properties: - propertyName: - type: string - minLength: 1 - mapping: - type: object - additionalProperties: - $ref: '#/components/schemas/Schema' - items: - oneOf: - - type: array - items: - $ref: '#/components/schemas/Schema' - - $ref: '#/components/schemas/Schema' - properties: - type: object - additionalProperties: - $ref: '#/components/schemas/Schema' - additionalProperties: - oneOf: - - $ref: '#/components/schemas/Schema' - - type: boolean - default: true - description: - type: string - format: - type: string - default: {} - nullable: - type: boolean - default: false - readOnly: - type: boolean - default: false - writeOnly: - type: boolean - default: false - example: {} - examples: {} - deprecated: - type: boolean - default: false - contentMediaType: - type: string - contentEncoding: - type: string - contentSchema: - type: string - additionalProperties: false - Metadata: - type: object - properties: - title: - type: string - role: - type: string - href: - type: string - AdditionalParameter: - required: - - name - - value - type: object - properties: - name: - type: string - value: - type: array - items: - oneOf: - - type: string - - type: number - - type: integer - - type: array - items: - type: object - - type: object - TransmissionMode: - type: string - default: value - enum: - - value - - reference - #------------------------------------------------------ - # Thematic objects - #------------------------------------------------------ - Capabilities: - required: - - links - type: object - properties: - title: - type: string - example: Example processing server - description: - type: string - example: Example server implementing the OGC API - Processes 1.0 Standard - links: - type: array - items: - $ref: '#/components/schemas/Link' - ConformanceDeclaration: - required: - - conformsTo - type: object - properties: - conformsTo: - type: array - items: - type: string - example: http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/core - ProcessList: - required: - - links - - processes - type: object - properties: - processes: - type: array - items: - $ref: '#/components/schemas/ProcessSummary' - links: - type: array - items: - $ref: '#/components/schemas/Link' - ProcessDescription: - allOf: - - $ref: '#/components/schemas/ProcessSummary' - - type: object - properties: - inputs: - type: object - additionalProperties: - $ref: '#/components/schemas/InputDescription' - outputs: - type: object - additionalProperties: - $ref: '#/components/schemas/OutputDescription' - ProcessRequest: - type: object - properties: - inputs: - type: object - additionalProperties: {} - outputs: - type: object - additionalProperties: - $ref: '#/components/schemas/Output' - response: - $ref: '#/components/schemas/ResponseType' - subscriber: - $ref: '#/components/schemas/Subscriber' - ProcessSummary: - allOf: - - $ref: '#/components/schemas/DescriptionType' - - required: - - id - - version - type: object - properties: - id: - type: string - version: - type: string - jobControlOptions: - type: array - items: - $ref: '#/components/schemas/JobControlOptions' - outputTransmission: - type: array - items: - $ref: '#/components/schemas/TransmissionMode' - links: - type: array - items: - $ref: '#/components/schemas/Link' - InputDescription: - allOf: - - $ref: '#/components/schemas/DescriptionType' - - required: - - schema - type: object - properties: - minOccurs: - type: integer - default: 1 - maxOccurs: - oneOf: - - type: integer - default: 1 - - $ref: '#/components/schemas/MaxOccurs' - schema: - $ref: '#/components/schemas/Schema' - OutputDescription: - allOf: - - $ref: '#/components/schemas/DescriptionType' - - required: - - schema - type: object - properties: - schema: - $ref: '#/components/schemas/Schema' - Output: - type: object - properties: - format: - $ref: '#/components/schemas/Format' - transmissionMode: - $ref: '#/components/schemas/TransmissionMode' - ResponseType: - type: string - default: raw - enum: - - raw - - document - Subscriber: - required: - - successUrl - type: object - properties: - successUri: - type: string - format: uri - inProgressUri: - type: string - format: uri - failedUri: - type: string - format: uri - description: |- - Optional URIs for callbacks for this job. - - Support for this parameter is not required and the parameter may be - removed from the API definition, if conformance class **'callback'** - is not listed in the conformance declaration under `/conformance`. - JobStatus: - type: string - nullable: false - enum: - - accepted - - running - - successful - - failed - - dismissed - JobType: - type: string - enum: - - process - JobControlOptions: - type: string - enum: - - sync-execute - - async-execute - - dismiss - JobList: - required: - - jobs - - links - type: object - properties: - jobs: - type: array - items: - $ref: '#/components/schemas/JobInfo' - links: - type: array - items: - $ref: '#/components/schemas/Link' - JobInfo: - required: - - jobID - - status - - type - type: object - properties: - processID: - type: string - type: - $ref: '#/components/schemas/JobType' - jobID: - type: string - status: - $ref: '#/components/schemas/JobStatus' - message: - type: string - created: - type: string - format: date-time - started: - type: string - format: date-time - finished: - type: string - format: date-time - updated: - type: string - format: date-time - progress: - maximum: 100 - minimum: 0 - type: integer - links: - type: array - items: - $ref: '#/components/schemas/Link' - # Extension of OGC API / Processes core v1 - traceback: - type: array - items: - type: string - JobResults: - type: object - additionalProperties: - $ref: '#/components/schemas/InlineOrRefValue' diff --git a/tools/sync_versions.py b/tools/sync_versions.py index 0b8a763..cf7db31 100644 --- a/tools/sync_versions.py +++ b/tools/sync_versions.py @@ -8,7 +8,7 @@ import tomlkit # List of workspaces to update -workspace_names = ["s2gos-common", "s2gos-server", "s2gos-client"] +workspace_names = ["s2gos-server", "s2gos-client"] def main(): From 98401dd5819c15aec890d24d6523eda33615c98b Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Mon, 10 Nov 2025 17:21:53 +0100 Subject: [PATCH 08/16] Update --- pixi.lock | 23 ++++++----------------- pyproject.toml | 4 ++-- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/pixi.lock b/pixi.lock index e30a132..ac92814 100644 --- a/pixi.lock +++ b/pixi.lock @@ -8783,30 +8783,19 @@ packages: - pypi: ./s2gos-client name: s2gos-client version: 0.0.6.dev0 - sha256: 6d6090cfc42bd9ee1a015f10dc18f9643b61adeb3f07ad95f0de26bc66098ef6 + sha256: 34ea841cfbfbace434b60202d06cbdd1409be7295fe481e2d6f9c5a117c016b5 requires_dist: - - click - - pydantic - - pyyaml - - typer - - uri-template - - httpx - - cuiman - - gavicore + - cuiman>=0.0.8 + - gavicore>=0.0.8 requires_python: '>=3.10' editable: true - pypi: ./s2gos-server name: s2gos-server version: 0.0.6.dev0 - sha256: 9689e8151fb46e2444a32f0e404c1bee19fd4ea5b4fe9e45ee1b72e3c60073b8 + sha256: 23611f6817b11268d52492257c18c6a634f8cd7b27cb7adc746fa8135aee59ce requires_dist: - - fastapi - - pydantic - - pyyaml - - typer - - uvicorn - - gavicore - - wraptile + - gavicore>=0.0.8 + - wraptile>=0.0.8 requires_python: '>=3.10' editable: true - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.21-h7ab7c64_0.conda diff --git a/pyproject.toml b/pyproject.toml index a1cff29..45de1a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -108,8 +108,8 @@ python_version = "3.10" check_untyped_defs = true disable_error_code = ["valid-type", "import-untyped"] exclude = [ - "s2gos-client/src/test", - "s2gos-server/src/test", + "s2gos-client/tests", + "s2gos-server/tests", "tools", ] From f0fb0ccdb02e858b1acf1b25c18d96b0c5b96e49 Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Mon, 10 Nov 2025 17:34:15 +0100 Subject: [PATCH 09/16] synced versions --- pixi.lock | 8 ++++---- s2gos-client/pyproject.toml | 2 +- s2gos-server/pyproject.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pixi.lock b/pixi.lock index ac92814..e7f6490 100644 --- a/pixi.lock +++ b/pixi.lock @@ -8782,8 +8782,8 @@ packages: timestamp: 1750189141795 - pypi: ./s2gos-client name: s2gos-client - version: 0.0.6.dev0 - sha256: 34ea841cfbfbace434b60202d06cbdd1409be7295fe481e2d6f9c5a117c016b5 + version: 0.1.0.dev0 + sha256: 169c3f4b20de4b2267e655681771927382285c53a4b4cc92bea887965d0df1d3 requires_dist: - cuiman>=0.0.8 - gavicore>=0.0.8 @@ -8791,8 +8791,8 @@ packages: editable: true - pypi: ./s2gos-server name: s2gos-server - version: 0.0.6.dev0 - sha256: 23611f6817b11268d52492257c18c6a634f8cd7b27cb7adc746fa8135aee59ce + version: 0.1.0.dev0 + sha256: f4c7000a30dba249ffdc11683ec6b64b912eb0d59aa5225ff5e497a5532e431f requires_dist: - gavicore>=0.0.8 - wraptile>=0.0.8 diff --git a/s2gos-client/pyproject.toml b/s2gos-client/pyproject.toml index cf7f26e..6998927 100644 --- a/s2gos-client/pyproject.toml +++ b/s2gos-client/pyproject.toml @@ -4,7 +4,7 @@ [project] name = "s2gos-client" -version = "0.0.6.dev0" +version = "0.1.0.dev0" description = "Python client for the ESA DTE-S2GOS synthetic scene generator service" readme = "README.md" authors = [ diff --git a/s2gos-server/pyproject.toml b/s2gos-server/pyproject.toml index af74b5a..e6fae2c 100644 --- a/s2gos-server/pyproject.toml +++ b/s2gos-server/pyproject.toml @@ -4,7 +4,7 @@ [project] name = "s2gos-server" -version = "0.0.6.dev0" +version = "0.1.0.dev0" description = "Python server for the ESA DTE-S2GOS synthetic scene generator service" readme = "README.md" authors = [ From 957c8e321a2e5579a4a3faff9d0317f21bb9c18d Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Wed, 12 Nov 2025 10:35:11 +0100 Subject: [PATCH 10/16] Updated README --- README.md | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++- pixi.lock | 20 +++--- 2 files changed, 185 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0ff9d9f..64f021d 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,181 @@ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v0.json)](https://github.com/charliermarsh/ruff) [![License](https://img.shields.io/github/license/s2gos-dev/s2gos-controller)](https://github.com/s2gos-dev/s2gos-controller) -# s2gos-controller +# DTE-S2GOS Control Layer -Python control layer for ESA DTE-S2GOS synthetic scene generator service +Python control layer for the synthetic EO scene simulator service of the +[ESA DTE-S2GOS project](https://dte-s2gos.rayference.eu/). + +

    + s2gos logo +

    + +--- _Note, this project and its documentation is still in an early development stage._ + +## Description + +This project hosts two Python packages: + +* `s2gos-client` - CLI, GUI, and API clients that allow for interaction + with the S2GOS scene simulator service. +* `s2gos-server` - a FastAPI-based implementation of the + [OGC API - Processes](https://ogcapi.ogc.org/processes/) that is wrapped around + the S2GOS scene simulator service based on [Apache Airflow](https://airflow.apache.org/). + +## Installation + +### Using pip + +The S2GOS controller packages are not yet deployed on PyPI, therefore +installing it as a package using `pip` is not yet available. + +### Using conda/mamba + +The S2GOS controller packages are not yet deployed on conda-forge, therefore +installing it using as a conda package using `conda` or `mamba` is not yet available. + +### Using pixi + +The S2GOS controller packages are not yet deployed on conda-forge, therefore +installing it as a conda package using `pixi` is not yet available. + +### Using GitHub + +To install the S2GOS controller packages from their sources on GitHub you'll +need to install both [git](https://git-scm.com/install/) and +[pixi](https://pixi.sh/latest/installation/) first. Then: + +```bash +git clone https://github.com/eo-tools/sen4cap-client.git +cd s2gos-controller +pixi install +pixi shell +``` + +The installed development environment includes also JupyterLab so the recommended +way to get started is to take a look at the notebooks in the `notebooks` folder. + +```bash +cd notebooks +jupyter-lab +``` + +## Getting started + +After installing the S2GOS controller packages in your Python environment +and activating it (conda/mamba: `conda activate `, pixi: `pixi shell`) +make sure the respective command-line tools are accessible: Type + +```bash +s2gos-server --help +``` + +and + +```bash +s2gos-client --help +``` + +to get an overview of the available commands and options. + +You can then run the S2GOS server with one of the development services +or use the deployed server. To run the development service with a local +process executor run + +```bash +s2gos-server dev -- wraptile.services.local:service +``` + +To run the S2GOS gateway server with a local Airflow instance (assuming +the local Airflow webserver runs on http://localhost:8080): + +```bash +s2gos-server dev -- wraptile.services.airflow:service --airflow-password=abcd1234 +``` + +The next step is configure the client, which will also serve as default configuration +for the client's Python API and its GUI: + +```bash +s2gos-client configure +``` + +Test: + +```bash +s2gos-client list-processes +``` + +## Development + +Install the S2GOS controller packages as described in +[Installation / Using GitHub](#using-github) above. + +### Linting and Testing + +To run all checks, execute + +```commandline +pixi run checks +``` + +To run all tests, execute + +```commandline +pixi run tests +``` + +To generate a coverage report, execute + +```commandline +pixi run coverage +``` + +### Implementing Enhancements + +The S2GOS controller code relies heavily on the +[Eozilla](https://eo-tools.github.io/eozilla/) packages + +* [wraptile](https://github.com/eo-tools/eozilla/tree/main/wraptile), + which provides the gateway server implementation, +* [cuiman](https://github.com/eo-tools/eozilla/tree/main/cuiman), + which provides the client CLI, GUI, and API implementations, and +* [gavicore](https://github.com/eo-tools/eozilla/tree/main/gavicore) + which provides common OGC model classes and basic utilities. + +Should S2GOS controller require non-S2GOS-specific enhancements it +would likely be best to implement the required changes in the respective +Eozilla packages. For this, check out the Eozilla sources directly next +to this project's sources to achieve this folder structure: + +```commandline + / + ├── s2gos-controller/ + │ ├── s2gos-client/ + │ ├── s2gos-server/ + │ └── ... + └── eozilla/ + ├── appligator/ + ├── cuiman/ + ├── gavicore/ + ├── procodile/ + ├── wraptile/ + └── ... +``` + +Then, during development, change `sen4cap-controller/pyproject.toml` +as follows + +1. Comment out the dependencies `cuiman`, `gavicore`, and `wraptile` in the + `[project.dependencies]` table. + +2. Uncomment the editable PyPI dependencies for `cuiman`, `gavicore`, + and `wraptile` in the `[tool.pixi.pypi-dependencies]` table. + +Then run once more + +```commandline +pixi install +``` diff --git a/pixi.lock b/pixi.lock index 3bece08..4468254 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1179,8 +1179,8 @@ packages: requires_python: ~=3.9 - pypi: ../eozilla/appligator name: appligator - version: 0.0.8.dev0 - sha256: 6a4c923c2c6a478fd7d6efd2bf686acef4036328ec7697125e07fc3b77beff23 + version: 0.0.8 + sha256: 02c0f3d145b3b7cec7bcc0e4efb1185ffeb9c6e5491e0603e2e4262c74e9f620 requires_dist: - pydantic - pyyaml @@ -2634,8 +2634,8 @@ packages: timestamp: 1749539269244 - pypi: ../eozilla/cuiman name: cuiman - version: 0.0.8.dev0 - sha256: c2d45f9ba8268315d501434e507801678cc9038cebf78496e83a08a9faeca910 + version: 0.0.8 + sha256: 871aaa2a3816d3e4ff13bdf7b7a8e1350334cc4c9c31b24e4d1e9df2831e80f4 requires_dist: - click - panel @@ -3051,8 +3051,8 @@ packages: timestamp: 1748101667956 - pypi: ../eozilla/gavicore name: gavicore - version: 0.0.8.dev0 - sha256: 2f554fb6cb2530441f8a6ef8aa0c639ad7b4f8141ee99e9bec3eb3eb8a417dec + version: 0.0.8 + sha256: 488145ac6c86f4b19f5169523deab4ab235b1edb34422b14242df95c6e9e91e6 requires_dist: - click - pydantic @@ -7755,8 +7755,8 @@ packages: timestamp: 1747339794916 - pypi: ../eozilla/procodile name: procodile - version: 0.0.8.dev0 - sha256: bcfc4f38f4679048eb6b9d2896f5780674d18ca03d90b7a8726f300995953996 + version: 0.0.8 + sha256: 761ceddd0d3ac3b5717e1fa18c73ac7f949c2fd57e621dde38e721aea31d589b requires_dist: - pydantic - pyyaml @@ -9885,8 +9885,8 @@ packages: timestamp: 1736870265811 - pypi: ../eozilla/wraptile name: wraptile - version: 0.0.8.dev0 - sha256: 18aebc189b21453308d28597524a9585b3d999ab3fa52d90fe8a6e3665ced6bc + version: 0.0.8 + sha256: 436c794e970c9aebbbbe51a9454f8c7c395a8df52cebed220663569b8b682bf7 requires_dist: - fastapi - pydantic From 5bfa4d2f963bed98942f706fc1c2180f772d06c7 Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Wed, 12 Nov 2025 10:40:20 +0100 Subject: [PATCH 11/16] Added logo --- docs/assets/logo-full.svg | 114 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 docs/assets/logo-full.svg diff --git a/docs/assets/logo-full.svg b/docs/assets/logo-full.svg new file mode 100644 index 0000000..2ccd209 --- /dev/null +++ b/docs/assets/logo-full.svg @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From a1c53f1888028336640d3b8fcb49b44370dbdaf5 Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Wed, 12 Nov 2025 11:08:05 +0100 Subject: [PATCH 12/16] Updated lock --- pixi.lock | 8819 +++++++++++++++++++++++++++-------------------------- 1 file changed, 4550 insertions(+), 4269 deletions(-) diff --git a/pixi.lock b/pixi.lock index 4468254..598d237 100644 --- a/pixi.lock +++ b/pixi.lock @@ -9,1096 +9,1107 @@ environments: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-doc-0.0.4-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.9.0-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/argcomplete-3.6.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argcomplete-3.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-21.2.0-py313h536fd9c_5.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.0.5-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.3.0-pyh71513ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.0-hbfa7f16_15.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.2-h5e3027f_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.3-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-hafb2847_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.4-h76f0014_12.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.2-h015de20_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.20.1-hdfce8c9_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.1-h1e5e6c0_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.8.1-h5e174a9_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-hafb2847_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-hafb2847_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.32.8-ha15c642_6.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.510-h4607db7_10.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.14.0-h5cfcd09_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.10.0-h113e628_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.13.0-h3cf044e_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.8.0-h736e048_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.12.0-ha633028_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyh71513ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.1-h194c533_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.8-h346e085_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.5-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h7e655bb_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.6-h1deb5b9_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-had4b759_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.2-hbff472d_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-h8ba2272_8.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.8.6-h493c25d_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h7e655bb_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h7e655bb_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.0-h719b17a_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h522d481_6.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.1-h3a458e0_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.2-h3a5f585_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.15.0-h2a74896_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.11.0-h3d7a050_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.13.0-hf38f1be_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports-1.0-pyhd8ed1ab_5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports.tarfile-1.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backrefs-5.8-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.13.4-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/black-25.1.0-py313h78bf25f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.2.0-h82add2a_4.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/bokeh-3.7.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py313h46c70d0_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bokeh-3.8.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313h09d1b84_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.6.15-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.6.15-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py313hfab6e84_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py313h33d0bda_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.9.1-py313h8060acc_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/crc32c-2.7.1-py313h536fd9c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-45.0.4-py313h6556f6e_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cytoolz-1.0.1-py313h536fd9c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2025.5.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.5.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/datamodel-code-generator-0.33.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.11.3-py313h3dea7bd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/crc32c-2.8-py313h54dd161_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-46.0.3-py313hafb0bba_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cytoolz-1.1.0-py313h07c4f96_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2025.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/datamodel-code-generator-0.35.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.14-py313h46c70d0_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.17-py313h5d5ffb9_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/deprecated-1.2.18-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.9-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/distributed-2025.5.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.7.0-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/deprecated-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/distributed-2025.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.8.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/donfig-0.8.1.post1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/editables-0.5-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.2.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.2.0-hd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.3.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.115.14-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.7-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.121.1-h4c1cb5d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.16-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-core-0.121.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/genson-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.7.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.15.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatch-1.14.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.27.0-pypyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/httptools-0.6.4-py313h536fd9c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/httptools-0.7.1-py313h07c4f96_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperlink-21.0.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/inflect-7.5.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh3099207_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.31.0-pyha191276_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipyleaflet-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.3.0-pyhfa0c392_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.7.0-pyh53cf698_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets_bokeh-1.6.0-pyha770c72_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/isort-6.0.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isort-6.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.classes-3.4.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.context-6.0.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.functools-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.functools-4.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jeepney-0.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.12.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-3.0.0-py313h78bf25f_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.24.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.4.1-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.24.0-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.12.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-3.0.0-py313h78bf25f_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.25.1-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.25.1-he01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-1.1.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.5-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.8.1-pyh31011fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_leaflet-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.16.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.4.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.4.10-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.15-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupytext-1.17.3-pyh80e38bb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.16-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupytext-1.18.1-pyh80e38bb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.6.0-pyha804496_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h1423503_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1aa0949_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20250127.1-cxx17_hbbce691_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-20.0.0-h314c690_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-20.0.0-hcb10f89_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-20.0.0-hcb10f89_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-20.0.0-h1bed206_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-32_h59b9bed_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb9d3cd8_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-32_he106b2a_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20250512.1-cxx17_hba17884_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-22.0.0-h99e40f8_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-22.0.0-h635bf11_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-22.0.0-h8c2c5c3_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-22.0.0-h635bf11_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-22.0.0-h3f74fd7_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-38_h4a7cf45_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-h09219d5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hd53d788_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-h02bd7ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-38_h0358290_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.14.1-h332b0f4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.2-h3618099_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.36.0-hc4361e1_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.36.0-h0121fbd_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.71.0-h8e591d7_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-32_h7ac8fdf_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.1-h32235b2_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.73.1-h3288cfb_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-38_h47877c9_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hd1b1c89_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libparquet-20.0.0-h081d1f1_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.49-h943b412_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.29.3-h501fc15_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2024.07.02-hba17884_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libparquet-22.0.0-h7376487_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.50-h421ea60_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h7b12aa8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.1-h6cd9bfd_6.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.21.0-h0e7cc3e_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.10.0-h202a827_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.0-hb04c3b8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/linkify-it-py-2.0.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-4.4.4-py313h8756d67_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-4.4.5-py313h28739b2_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.8.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py313h8060acc_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.4.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mergedeep-1.3.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.3-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-1.6.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-autorefs-1.4.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-autorefs-1.4.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-get-deps-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-jupyter-0.25.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-9.6.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-9.7.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-extensions-1.3.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.29.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.16.12-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.1-py313h33d0bda_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.16.1-py313h536fd9c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.30.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.19.0-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.8.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py313h7037e92_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.18.2-py313h07c4f96_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-1.44.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.11.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hb482800_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.6-hed9df3c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hc388f54_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.6-h7d6f222_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h3f2d84a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.4.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.16.1-py313ha87cce1_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.0-py313h17eae1a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/orc-2.1.2-h17f744e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.16.1-py313h08cd8bf_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.4-py313hf6604e3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.1-hd747db4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/paginate-0.5.7-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.0-py313ha87cce1_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.8.2-ha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.8.2.1-ha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/panel-1.7.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/panel-1.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/param-2.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.5-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.45-hc749103_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py313h8db990d_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh145f28c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py313h50355cd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.8-unix_hf108a03_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.8-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.22.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.0.0-py313h536fd9c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.23.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.52-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.1.3-py313h54dd161_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-20.0.0-py313h78bf25f_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-20.0.0-py313he5f92c8_0_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-22.0.0-py313h78bf25f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-22.0.0-py313he109ebe_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.33.2-py313h4b2b08d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.4-pyh3cfb1c2_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.41.5-py313h843e2db_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.5-hec9711d_102_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.1.1-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-7.0.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.9-h4df99d1_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-multipart-0.0.20-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-7_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyviz_comms-3.0.6-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.2-py313h8060acc_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-env-tag-1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.0.0-py313h8e95178_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/re2-2024.07.02-h9925aae_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hfb55c3c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.36.2-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.0.0-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/rich-toolkit-0.11.3-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.25.1-py313h4b2b08d_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.12.0-py313h67f39b2_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.21-h7ab7c64_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/secretstorage-3.3.3-py313h78bf25f_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rich-toolkit-0.15.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.28.0-py313h843e2db_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.14.4-h813ae00_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.6.0-h8399546_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/secretstorage-3.4.0-py313h78bf25f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh0d859eb_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.1-h8bd8927_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/starlette-0.46.2-pyh81abbef_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/starlette-0.49.2-pyhfdc7a7d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh0d859eb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.13.3-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-1.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py313h536fd9c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-1.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py313h07c4f96_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traittypes-0.2.1-pyh9f0ad1d_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2025.5.9.12-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traittypes-0.2.3-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2025.9.11.17-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.4.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.16.0-pyh167b9f4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.16.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.16.0-hf964461_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20250516-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.14.0-h32cad80_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhdb1f59b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h65a100f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uc-micro-py-1.0.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/userpath-1.9.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.7.14-h2f11bb8_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.34.3-pyh31011fe_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.34.3-h31011fe_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/uvloop-0.21.0-py313h536fd9c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.31.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/watchdog-6.0.0-py313h78bf25f_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/watchfiles-1.1.0-py313h920b4c0_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.11.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.9.8-h76e24b7_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.38.0-pyh31011fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.38.0-h31011fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/uvloop-0.22.1-py313h07c4f96_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.35.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/watchdog-6.0.0-py313h78bf25f_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/watchfiles-1.1.1-py313h5c7d99a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.8.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/websockets-15.0.1-py313h536fd9c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.14-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/wrapt-1.17.2-py313h536fd9c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.6.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/websockets-15.0.1-py313h54dd161_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.15-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/wrapt-1.17.3-py313h07c4f96_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.10.1-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-3.0.8-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h3b0a872_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-3.1.3-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py313h536fd9c_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.2.5-hde8ca8f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py313h54dd161_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda - pypi: https://files.pythonhosted.org/packages/53/c7/d168dd2e2120b1a61ffdcf6eaa6d992620a793d3bf7e12a59704eda1d83b/apache_airflow_client-3.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/24/ce/c8a41cb0f3044990c8afbdc20c853845a9e940995d4e0cffecafbb5e927b/mkdocs_mermaid2_plugin-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl - pypi: ../eozilla/appligator - pypi: ../eozilla/cuiman - pypi: ../eozilla/gavicore - pypi: ../eozilla/procodile - pypi: ../eozilla/wraptile - - pypi: ./s2gos-app-ex - pypi: ./s2gos-client - - pypi: ./s2gos-common - pypi: ./s2gos-server osx-64: + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-doc-0.0.4-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.9.0-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.11.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/argcomplete-3.6.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argcomplete-3.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/argon2-cffi-bindings-21.2.0-py313ha37c0e0_5.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/argon2-cffi-bindings-25.1.0-py313hf050af9_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.0.5-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.3.0-pyh71513ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-auth-0.9.0-h11bee3c_15.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-cal-0.9.2-h80a239a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-common-0.12.3-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-compression-0.3.1-hdea44ad_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-event-stream-0.5.4-h01412b5_12.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-http-0.10.2-ha1444c5_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-io-0.20.1-h550966a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-mqtt-0.13.1-h90c2deb_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-s3-0.8.1-hb3f0f26_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-sdkutils-0.2.4-hdea44ad_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-checksums-0.2.7-hdea44ad_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-crt-cpp-0.32.8-h47a58cb_6.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-sdk-cpp-1.11.510-h894e209_10.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/azure-core-cpp-1.14.0-h9a36307_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/azure-identity-cpp-1.10.0-ha4e2ba9_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-blobs-cpp-12.13.0-h3d2f5f1_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-common-cpp-12.8.0-h1ccc5ac_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-files-datalake-cpp-12.12.0-h86941f0_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyh71513ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-auth-0.9.1-hd76a34f_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-cal-0.9.8-h6b06ba2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-common-0.12.5-h8616949_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-compression-0.3.1-h7df70e9_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-event-stream-0.5.6-h0ddc0d0_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-http-0.10.7-ha9fb31a_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-io-0.23.2-hccfe1ea_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-mqtt-0.13.3-ha2a017f_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-s3-0.8.6-hedfbfa3_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-sdkutils-0.2.4-h7df70e9_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-checksums-0.2.7-h7df70e9_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-crt-cpp-0.35.0-h7e7cb56_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-sdk-cpp-1.11.606-hf0dd41a_6.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/azure-core-cpp-1.16.1-he2a98a9_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/azure-identity-cpp-1.13.2-h0e8e1c8_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-blobs-cpp-12.15.0-h388f2e7_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-common-cpp-12.11.0-h56a711b_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-files-datalake-cpp-12.13.0-h1984e67_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports-1.0-pyhd8ed1ab_5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports.tarfile-1.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backrefs-5.8-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.13.4-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.2.0-h82add2a_4.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/bokeh-3.7.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.1.0-py313h14b76d3_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bokeh-3.8.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.2.0-py313hd4eab94_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.5-hf13058a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.6.15-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.6.15-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.17.1-py313h49682b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-2.0.0-py313hf57695f_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.2-py313ha0b1807_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.9.1-py313h717bdf5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/crc32c-2.7.1-py313h63b0ddb_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/cytoolz-1.0.1-py313h63b0ddb_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2025.5.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.5.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/datamodel-code-generator-0.33.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/debugpy-1.8.14-py313h14b76d3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py313h5eff275_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.11.3-py313h0f4d31d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/crc32c-2.8-py313hcb05632_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cytoolz-1.1.0-py313hf050af9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2025.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/datamodel-code-generator-0.35.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/debugpy-1.8.17-py313hff8d55d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/deprecated-1.2.18-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.9-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/distributed-2025.5.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.7.0-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/deprecated-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/distributed-2025.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.8.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/donfig-0.8.1.post1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/editables-0.5-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.2.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.2.0-hd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.3.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.115.14-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.7-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.121.1-h4c1cb5d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.16-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-core-0.121.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/genson-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gflags-2.2.2-hac325c4_1005.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/glog-0.7.1-h2790a97_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.7.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.15.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatch-1.14.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.27.0-pypyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/httptools-0.6.4-py313h63b0ddb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/httptools-0.7.1-py313hf050af9_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperlink-21.0.0-pyh29332c3_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-75.1-h120a0e1_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/inflect-7.5.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh57ce528_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.31.0-pyh5552912_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipyleaflet-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.3.0-pyhfa0c392_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.7.0-pyh53cf698_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets_bokeh-1.6.0-pyha770c72_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/isort-6.0.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isort-6.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.classes-3.4.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.context-6.0.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.functools-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.functools-4.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.12.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/jsonpointer-3.0.0-py313habf4b1d_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.24.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.4.1-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.24.0-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.12.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/jsonpointer-3.0.0-py313habf4b1d_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.25.1-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.25.1-he01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-1.1.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.5-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.8.1-pyh31011fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_leaflet-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.16.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.4.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.4.10-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.15-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupytext-1.17.3-pyh80e38bb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.16-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupytext-1.18.1-pyh80e38bb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.6.0-pyh534df25_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.3-h37d8d59_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.17-h72f5680_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hcca01a6_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libabseil-20250127.1-cxx17_h0e468a2_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-20.0.0-hd0d6b81_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-acero-20.0.0-hdc53af8_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-dataset-20.0.0-hdc53af8_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-substrait-20.0.0-ha37b807_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-32_h7f60823_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.1.0-h6e16a3a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.1.0-h6e16a3a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.1.0-h6e16a3a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-32_hff6cab4_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libabseil-20250512.1-cxx17_hfc00f1c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-22.0.0-hb95b15f_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-acero-22.0.0-h2db2d7d_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-compute-22.0.0-h7751554_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-dataset-22.0.0-h2db2d7d_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-substrait-22.0.0-h4653b8a_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-38_he492b99_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h105ed1c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h660c9da_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h2338291_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-38_h9b27e0a_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcrc32c-1.1.2-he49afe7_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.14.1-h5dec5d8_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-20.1.7-hf95d169_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.24-hcc1b750_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.17.0-h7dd4100_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.5-h3d58e20_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libevent-2.1.12-ha90c15b_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.0-h240833e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.6-h281671d_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.13.3-h694c41f_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.13.3-h40dfd5c_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-5.0.0-14_2_0_h51e75f0_103.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-14.2.0-h51e75f0_103.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libgoogle-cloud-2.36.0-h777fda5_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libgoogle-cloud-storage-2.36.0-h3397294_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libgrpc-1.71.0-h7d722e6_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h4b5e92a_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.0-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-32_h236ab99_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.1-h21dd04a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.1-h694c41f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.1-h6912278_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h306097a_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-h336fb69_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgoogle-cloud-2.39.0-hed66dea_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgoogle-cloud-storage-2.39.0-h8ac052b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgrpc-1.73.1-h451496d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.2-h8616949_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-38_h859234e_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.64.0-hc7306c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.30-openmp_hbf64a52_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libopentelemetry-cpp-1.21.0-h30c661f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libopentelemetry-cpp-headers-1.21.0-h694c41f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libparquet-20.0.0-h283e888_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.49-h3c4a55f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libprotobuf-5.29.3-h1c7185b_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libre2-11-2024.07.02-h08ce7b7_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.30-openmp_h6006d49_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libopentelemetry-cpp-1.21.0-h7d3f41d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libopentelemetry-cpp-headers-1.21.0-h694c41f_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libparquet-22.0.0-habb56ca_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.50-h84aeda2_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libprotobuf-6.31.1-h03562ea_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libre2-11-2025.11.05-h554ac88_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libsodium-1.0.20-hfdf4475_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.50.1-h7cec44d_6.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.0-h86bffb9_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libthrift-0.21.0-h75589b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.0-h1167cee_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libutf8proc-2.10.0-h5b79583_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h4cb831e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.5.0-h6cf52b4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libthrift-0.22.0-h687e942_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libutf8proc-2.11.0-h64b4c5c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.13.8-h93c44a6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-h0ad03eb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h23bb396_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/linkify-it-py-2.0.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.7-ha54dae1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-21.1.5-h472b3d1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-4.4.4-py313hc9bb01a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-4.4.5-py313hab77a93_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-c-1.10.0-h240833e_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.8.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.2-py313h717bdf5_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.4.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.3-py313h0f4d31d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mergedeep-1.3.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.3-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-1.6.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-autorefs-1.4.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-autorefs-1.4.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-get-deps-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-jupyter-0.25.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-9.6.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-9.7.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-extensions-1.3.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.29.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.16.12-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.1.1-py313ha0b1807_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.16.1-py313h63b0ddb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.30.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.19.0-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.8.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.1.2-py313h5eff275_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.18.2-py313hf050af9_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-1.44.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.11.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hb482800_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.6-hed9df3c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hc388f54_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.6-h7d6f222_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/nlohmann_json-3.12.0-h92383a6_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.4.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/nlohmann_json-3.12.0-h53ec75d_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/numcodecs-0.16.1-py313h2e7108f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.3.0-py313hc518a0f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.3-h7fd6d84_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.5.0-hc426f3f_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/orc-2.1.2-h82caab2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/numcodecs-0.16.1-py313h2f264a9_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.3.4-py313ha99c057_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h87e8dc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/orc-2.2.1-hd1b02dc_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/paginate-0.5.7-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.0-py313h2e7108f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pandoc-3.8.2-h694c41f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.3-py313h2f264a9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pandoc-3.8.2.1-h694c41f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/panel-1.7.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/panel-1.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/param-2.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.5-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pillow-11.2.1-py313h0c4f865_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh145f28c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pillow-12.0.0-py313he918548_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.8-unix_hf108a03_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.8-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/prometheus-cpp-1.3.0-h7802330_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.22.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.0.0-py313h63b0ddb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.23.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.52-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.1.3-py313hcb05632_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-20.0.0-py313habf4b1d_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-core-20.0.0-py313hc71e1e6_0_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-22.0.0-py313habf4b1d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-core-22.0.0-py313hff57800_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.33.2-py313hb35714d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.4-pyh3cfb1c2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.41.5-py313hcc225dc_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-core-11.1-py313h6971d95_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-framework-cocoa-11.1-py313h19a8f7f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-core-12.0-py313h07bcf3a_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-framework-cocoa-12.0-py313hf669bc3_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.5-hc3a4c56_102_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.1.1-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-7.0.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.9-h17c18a5_101_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.9-h4df99d1_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-multipart-0.0.20-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-7_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyviz_comms-3.0.6-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.2-py313h717bdf5_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.3-py313h0f4d31d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-env-tag-1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pyzmq-27.0.0-py313h2d45800_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/re2-2024.07.02-hf8a452e_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pyzmq-27.1.0-py312hb7d603e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/re2-2025.11.05-h7df6414_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.36.2-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.0.0-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/rich-toolkit-0.11.3-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.25.1-py313hb35714d_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.12.0-py313h1aad41e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rich-toolkit-0.15.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.28.0-py313hcc225dc_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.14.4-hd9f4cfa_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh31c8845_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/snappy-1.2.1-haf3c120_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/snappy-1.2.2-h25c286d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/starlette-0.46.2-pyh81abbef_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/starlette-0.49.2-pyhfdc7a7d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh31c8845_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.13.3-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-1.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.1-py313h63b0ddb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-1.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.2-py313hf050af9_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traittypes-0.2.1-pyh9f0ad1d_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2025.5.9.12-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traittypes-0.2.3-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2025.9.11.17-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.4.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.16.0-pyh167b9f4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.16.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.16.0-hf964461_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20250516-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.14.0-h32cad80_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhdb1f59b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h65a100f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uc-micro-py-1.0.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/userpath-1.9.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/uv-0.7.14-h6914f18_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.34.3-pyh31011fe_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.34.3-h31011fe_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/uvloop-0.21.0-py313hb558fbc_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.31.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/watchdog-6.0.0-py313h63b0ddb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/watchfiles-1.1.0-py313h3c055b9_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.11.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/uv-0.9.8-h3315dae_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.38.0-pyh31011fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.38.0-h31011fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/uvloop-0.22.1-py313hf050af9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.35.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/watchdog-6.0.0-py313h585f44e_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/watchfiles-1.1.1-py313ha265c4a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.8.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/websockets-15.0.1-py313h63b0ddb_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.14-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/wrapt-1.17.2-py313h63b0ddb_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.6.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/websockets-15.0.1-py313h6865ccc_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.15-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/wrapt-1.17.3-py313h585f44e_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.10.1-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h6e16a3a_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-libxdmcp-1.1.5-h00291cd_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-3.0.8-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/zeromq-4.3.5-h7130eaa_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-3.1.3-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zeromq-4.3.5-h6c33b1e_9.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.23.0-py313h63b0ddb_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.2.5-h55e386d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.25.0-py313hcb05632_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h8210216_2.conda - pypi: https://files.pythonhosted.org/packages/53/c7/d168dd2e2120b1a61ffdcf6eaa6d992620a793d3bf7e12a59704eda1d83b/apache_airflow_client-3.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/24/ce/c8a41cb0f3044990c8afbdc20c853845a9e940995d4e0cffecafbb5e927b/mkdocs_mermaid2_plugin-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl - pypi: ../eozilla/appligator - pypi: ../eozilla/cuiman - pypi: ../eozilla/gavicore - pypi: ../eozilla/procodile - pypi: ../eozilla/wraptile - - pypi: ./s2gos-app-ex - pypi: ./s2gos-client - - pypi: ./s2gos-common - pypi: ./s2gos-server win-64: - conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-doc-0.0.4-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.9.0-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/argcomplete-3.6.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argcomplete-3.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-21.2.0-py313ha7868ed_5.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.0.5-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.3.0-pyh71513ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.9.0-hd490b63_15.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.9.2-hd8a8e38_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.12.3-h2466b09_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.3.1-h5d0e663_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-event-stream-0.5.4-ha416645_12.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.10.2-h81282ae_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.20.1-hddf4d6c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-mqtt-0.13.1-h5c1ae27_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.8.1-h1e843c7_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.2.4-h5d0e663_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.2.7-h5d0e663_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-crt-cpp-0.32.8-h5d81255_6.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-sdk-cpp-1.11.510-h7deb975_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyh71513ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.9.1-h179d6b4_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.9.8-ha82e055_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.12.5-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.3.1-h83e01e5_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-event-stream-0.5.6-hd31a2bc_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.10.7-h4b68edd_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.23.2-h460b297_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-mqtt-0.13.3-hfde8714_8.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.8.6-haf2eb35_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.2.4-h83e01e5_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.2.7-h83e01e5_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-crt-cpp-0.35.0-hd7c148e_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-sdk-cpp-1.11.606-h2b076a5_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports-1.0-pyhd8ed1ab_5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports.tarfile-1.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backrefs-5.8-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.13.4-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.2.0-h82add2a_4.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/bokeh-3.7.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.1.0-py313h5813708_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bokeh-3.8.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313hf510273_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda - conda: https://conda.anaconda.org/conda-forge/win-64/c-ares-1.34.5-h2466b09_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.6.15-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-h4c7d964_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.6.15-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-1.17.1-py313ha7868ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh7428d3b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh7428d3b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py313h1ec8472_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.9.1-py313hb4c8b1a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.5-py313hd8ed1ab_102.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/crc32c-2.7.1-py313ha7868ed_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cytoolz-1.0.1-py313ha7868ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2025.5.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.5.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/datamodel-code-generator-0.33.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.14-py313h5813708_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py313hf069bd2_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.11.3-py313hd650c13_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/crc32c-2.8-py313h5fd188c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cytoolz-1.1.0-py313h5ea7bf4_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2025.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/datamodel-code-generator-0.35.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.17-py313h927ade5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/deprecated-1.2.18-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.9-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/distributed-2025.5.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.7.0-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/deprecated-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/distributed-2025.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.8.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/donfig-0.8.1.post1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/editables-0.5-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.2.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.2.0-hd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.3.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.115.14-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.7-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.121.1-h4c1cb5d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.16-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-core-0.121.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/genson-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.7.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.15.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatch-1.14.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.27.0-pypyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/httptools-0.6.4-py313ha7868ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/httptools-0.7.1-py313h5ea7bf4_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperlink-21.0.0-pyh29332c3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/inflect-7.5.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.2.1-h57928b3_1083.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh4bbf305_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.31.0-pyh6dadd2b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipyleaflet-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.3.0-pyh6be1c34_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.7.0-pyhe2676ad_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets_bokeh-1.6.0-pyha770c72_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/isort-6.0.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isort-6.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.classes-3.4.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.context-6.0.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.functools-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.functools-4.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.12.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/jsonpointer-3.0.0-py313hfa70ccb_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.24.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.4.1-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.24.0-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.12.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/jsonpointer-3.0.0-py313hfa70ccb_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.25.1-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.25.1-he01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-1.1.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.5-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.8.1-pyh5737063_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_leaflet-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.16.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.4.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.4.10-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.15-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupytext-1.17.3-pyh80e38bb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.16-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupytext-1.18.1-pyh80e38bb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.6.0-pyh7428d3b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libabseil-20250127.1-cxx17_h4eb7d71_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-20.0.0-hc090743_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-20.0.0-h7d8d6a5_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-20.0.0-h7d8d6a5_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-substrait-20.0.0-hb76e781_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-32_h641d27c_mkl.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.1.0-h2466b09_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.1.0-h2466b09_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.1.0-h2466b09_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-32_h5e41251_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libabseil-20250512.1-cxx17_habfad5f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-22.0.0-h0832232_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-22.0.0-h7d8d6a5_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-compute-22.0.0-h2db994a_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-22.0.0-h7d8d6a5_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-substrait-22.0.0-hf865cc0_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-38_hf2e6a31_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hc82b238_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-h431afc6_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-ha521d6b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-38_h2a3cdd5_mkl.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libcrc32c-1.1.2-h0e60522_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.14.1-h88aaa65_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.24-h76ddb4d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.17.0-h43ecb02_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libevent-2.1.12-h3671451_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.0-he0c23c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.13.3-h57928b3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.13.3-h0b5ce68_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.1.0-h1383e82_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.1.0-h1383e82_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-2.36.0-hf249c01_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-storage-2.36.0-he5eb982_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgrpc-1.71.0-h8c3449c_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.11.2-default_ha69328c_1001.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-h135ad9c_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.0-h2466b09_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-32_h1aa476e_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.1-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.1-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h1383e82_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h1383e82_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-2.39.0-h19ee442_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-storage-2.39.0-he04ea4c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgrpc-1.73.1-h317e13b_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.1-default_h64bd3f2_1002.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-38_hf9ab0e9_mkl.conda - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libparquet-20.0.0-ha850022_7_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.49-h7a4582a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libprotobuf-5.29.3-he9d8c4a_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libre2-11-2024.07.02-hd248061_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libparquet-22.0.0-h7051d1f_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.50-h7351971_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libprotobuf-6.31.1-hdcda5b4_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libre2-11-2025.11.05-h0eb2380_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.20-hc70643c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.50.1-hf5d6505_6.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.0-hf5d6505_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libthrift-0.21.0-hbe90ef8_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h05922d8_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libutf8proc-2.10.0-hff4702e_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.5.0-h3b0e114_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libthrift-0.22.0-h23985f6_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libutf8proc-2.11.0-h0b34c2f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.8-h442d1da_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h692994f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.1-h5d26750_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/linkify-it-py-2.0.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-21.1.5-hfa2b4ca_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/lz4-4.4.4-py313h05901a4_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lz4-4.4.5-py313h4bbca4b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/lz4-c-1.10.0-h2466b09_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.8.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.2-py313hb4c8b1a_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.4.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mergedeep-1.3.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.3-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-1.6.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-autorefs-1.4.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-autorefs-1.4.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-get-deps-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-jupyter-0.25.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-9.6.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-9.7.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-extensions-1.3.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.29.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.16.12-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.1-py313h1ec8472_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.16.1-py313ha7868ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.30.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.19.0-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2025.3.0-hac47afa_454.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.8.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.2-py313hf069bd2_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.18.2-py313h5ea7bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-1.44.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.11.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hb482800_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.6-hed9df3c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hc388f54_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.6-h7d6f222_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.4.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/numcodecs-0.16.1-py313hf91d08e_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.3.0-py313hefb8edb_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.3-h4d64b90_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.5.0-ha4e3fda_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/orc-2.1.2-h35764e3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/numcodecs-0.16.1-py313hc90dcd4_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.3.4-py313hce7ae62_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h24db6dd_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/orc-2.2.1-h7414dfc_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/paginate-0.5.7-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.3.0-py313hf91d08e_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pandoc-3.8.2-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.3.3-py313hc90dcd4_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pandoc-3.8.2.1-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/panel-1.7.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/panel-1.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/param-2.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.5-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.2.1-py313hda88b71_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh145f28c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-12.0.0-py313hf6db949_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.8-win_hba80fca_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.8-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.22.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.0.0-py313ha7868ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.23.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.52-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.1.3-py313h5fd188c_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-20.0.0-py313hfa70ccb_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-core-20.0.0-py313he812468_0_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-22.0.0-py313hfa70ccb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-core-22.0.0-py313h5921983_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.33.2-py313ha8a9a3c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.4-pyh3cfb1c2_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.41.5-py313hfbe8231_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.5-h7de537c_102_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.1.1-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-7.0.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.9-h09917c8_101_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.9-h4df99d1_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-multipart-0.0.20-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-7_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyviz_comms-3.0.6-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-307-py313h5813708_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-ctypes-0.2.3-py313hfa70ccb_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.2-py313hb4c8b1a_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-ctypes-0.2.3-py313hfa70ccb_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-env-tag-1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.0.0-py313h2100fd5_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/re2-2024.07.02-haf4117d_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.36.2-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312hbb5da91_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/re2-2025.11.05-ha104f34_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.0.0-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/rich-toolkit-0.11.3-pyh29332c3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.25.1-py313ha8a9a3c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.12.0-py313h784dc11_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rich-toolkit-0.15.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.28.0-py313hfbe8231_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.14.4-h15e3a1f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh5737063_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.1-h500f7fa_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/starlette-0.46.2-pyh81abbef_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.13.0-h62715c5_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/starlette-0.49.2-pyhfdc7a7d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-hd094cb3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh5737063_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.13.3-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-1.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.1-py313ha7868ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-1.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.2-py313h5ea7bf4_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traittypes-0.2.1-pyh9f0ad1d_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2025.5.9.12-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traittypes-0.2.3-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2025.9.11.17-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.4.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.16.0-pyh167b9f4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.16.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.16.0-hf964461_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20250516-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.14.0-h32cad80_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhdb1f59b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h65a100f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uc-micro-py-1.0.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/userpath-1.9.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.7.14-he94b42d_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.34.3-pyh5737063_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.34.3-h5737063_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_26.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_26.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.31.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.44.35208-h38c0c73_26.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/watchdog-6.0.0-py313hfa70ccb_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/watchfiles-1.1.0-py313hf3b5b86_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.11.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.9.8-h3bd95fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.38.0-pyh5737063_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.38.0-h5737063_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_32.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.35.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.44.35208-h38c0c73_32.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/watchdog-6.0.0-py313hfa70ccb_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/watchfiles-1.1.1-py313hf61f64f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.8.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/websockets-15.0.1-py313ha7868ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/websockets-15.0.1-py313h5fd188c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.15-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/wrapt-1.17.2-py313ha7868ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.6.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/wrapt-1.17.3-py313h5ea7bf4_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.10.1-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-h0e40799_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-h0e40799_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h8ffe710_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-3.0.8-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-ha9f60a1_7.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-3.1.3-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h5bddc39_9.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.23.0-py313ha7868ed_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.2.5-h32d8bfd_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.25.0-py313h5fd188c_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-hbeecb71_2.conda - pypi: https://files.pythonhosted.org/packages/53/c7/d168dd2e2120b1a61ffdcf6eaa6d992620a793d3bf7e12a59704eda1d83b/apache_airflow_client-3.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/24/ce/c8a41cb0f3044990c8afbdc20c853845a9e940995d4e0cffecafbb5e927b/mkdocs_mermaid2_plugin-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl - pypi: ../eozilla/appligator - pypi: ../eozilla/cuiman - pypi: ../eozilla/gavicore - pypi: ../eozilla/procodile - pypi: ../eozilla/wraptile - - pypi: ./s2gos-app-ex - pypi: ./s2gos-client - - pypi: ./s2gos-common - pypi: ./s2gos-server packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -1137,6 +1148,28 @@ packages: purls: [] size: 49468 timestamp: 1718213032772 +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + sha256: a3967b937b9abf0f2a99f3173fa4630293979bd1644709d89580e7c62a544661 + md5: aaa2a381ccc56eac91d63b6c1240312f + depends: + - cpython + - python-gil + license: MIT + license_family: MIT + purls: [] + size: 8191 + timestamp: 1744137672556 +- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-doc-0.0.4-pyhcf101f3_0.conda + sha256: cc9fbc50d4ee7ee04e49ee119243e6f1765750f0fd0b4d270d5ef35461b643b1 + md5: 52be5139047efadaeeb19c6a5103f92a + depends: + - python >=3.10 + - python + license: MIT + purls: + - pkg:pypi/annotated-doc?source=hash-mapping + size: 14222 + timestamp: 1762868213144 - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 md5: 2934f256a8acfe48f6ebb4fce6cde29c @@ -1149,25 +1182,25 @@ packages: - pkg:pypi/annotated-types?source=hash-mapping size: 18074 timestamp: 1733247158254 -- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.9.0-pyh29332c3_0.conda - sha256: b28e0f78bb0c7962630001e63af25a89224ff504e135a02e50d4d80b6155d386 - md5: 9749a2c77a7c40d432ea0927662d7e52 +- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.11.0-pyhcf101f3_0.conda + sha256: 7378b5b9d81662d73a906fabfc2fb81daddffe8dc0680ed9cda7a9562af894b0 + md5: 814472b61da9792fae28156cb9ee54f5 depends: - exceptiongroup >=1.0.2 - idna >=2.8 - - python >=3.9 + - python >=3.10 - sniffio >=1.1 - typing_extensions >=4.5 - python constrains: - - trio >=0.26.1 + - trio >=0.31.0 - uvloop >=0.21 license: MIT license_family: MIT purls: - pkg:pypi/anyio?source=hash-mapping - size: 126346 - timestamp: 1742243108743 + size: 138159 + timestamp: 1758634638734 - pypi: https://files.pythonhosted.org/packages/53/c7/d168dd2e2120b1a61ffdcf6eaa6d992620a793d3bf7e12a59704eda1d83b/apache_airflow_client-3.0.2-py3-none-any.whl name: apache-airflow-client version: 3.0.2 @@ -1200,17 +1233,17 @@ packages: - pkg:pypi/appnope?source=hash-mapping size: 10076 timestamp: 1733332433806 -- conda: https://conda.anaconda.org/conda-forge/noarch/argcomplete-3.6.2-pyhd8ed1ab_0.conda - sha256: 66ffcf30550e0788d16090e4b4e8835290b15439bb454b0e217176a09dc1d500 - md5: eb9d4263271ca287d2e0cf5a86da2d3a +- conda: https://conda.anaconda.org/conda-forge/noarch/argcomplete-3.6.3-pyhd8ed1ab_0.conda + sha256: a2a1879c53b7a8438c898d20fa5f6274e4b1c30161f93b7818236e9df6adffde + md5: 8f37c8fb7116a18da04e52fa9e2c8df9 depends: - - python >=3.9 + - python >=3.10 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/argcomplete?source=hash-mapping - size: 42164 - timestamp: 1743726091226 + size: 42386 + timestamp: 1760975036972 - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda sha256: bea62005badcb98b1ae1796ec5d70ea0fc9539e7d59708ac4e7d41e2f4bb0bad md5: 8ac12aff0860280ee0cff7fa2cf63f3b @@ -1223,67 +1256,68 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/argon2-cffi?source=compressed-mapping + - pkg:pypi/argon2-cffi?source=hash-mapping size: 18715 timestamp: 1749017288144 -- conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-21.2.0-py313h536fd9c_5.conda - sha256: b17e5477dbc6a01286ea736216f49039d35335ea3283fa0f07d2c7cea57002ae - md5: 49fa2ed332b1239d6b0b2fe5e0393421 +- conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda + sha256: ad188ccc06a06c633dc124b09e9e06fb9df4c32ffc38acc96ecc86e506062090 + md5: 27bbec9f2f3a15d32b60ec5734f5b41c depends: - __glibc >=2.17,<3.0.a0 - cffi >=1.0.1 - - libgcc >=13 - - python >=3.13.0rc1,<3.14.0a0 + - libgcc >=14 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: MIT license_family: MIT purls: - pkg:pypi/argon2-cffi-bindings?source=hash-mapping - size: 34900 - timestamp: 1725356714671 -- conda: https://conda.anaconda.org/conda-forge/osx-64/argon2-cffi-bindings-21.2.0-py313ha37c0e0_5.conda - sha256: d8b9baae87e315b0106d85eb769d7dcff9691abce4b313d8ca410c26998217b2 - md5: 2a9ccef1e31a58c4a77ffc92d3cc9c55 + size: 35943 + timestamp: 1762509452935 +- conda: https://conda.anaconda.org/conda-forge/osx-64/argon2-cffi-bindings-25.1.0-py313hf050af9_2.conda + sha256: e2644e87c26512e38c63ace8fc19120a472c0983718a8aa264862c25294d0632 + md5: 1fedb53ffc72b7d1162daa934ad7996b depends: - __osx >=10.13 - cffi >=1.0.1 - - python >=3.13.0rc1,<3.14.0a0 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: MIT license_family: MIT purls: - pkg:pypi/argon2-cffi-bindings?source=hash-mapping - size: 32046 - timestamp: 1725356858173 -- conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-21.2.0-py313ha7868ed_5.conda - sha256: 36b79f862177b3a104762f68664e445615e7c831ca5fe76dc4596ad531ed46a3 - md5: 6d6dbb065c660e9e358b32bdab9ada31 + size: 33301 + timestamp: 1762509795647 +- conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda + sha256: 3f8a1affdfeb2be5289d709e365fc6e386d734773895215cf8cbc5100fa6af9a + md5: eabb4b677b54874d7d6ab775fdaa3d27 depends: - cffi >=1.0.1 - - python >=3.13.0rc1,<3.14.0a0 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: - pkg:pypi/argon2-cffi-bindings?source=hash-mapping - size: 34467 - timestamp: 1725357154522 -- conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.3.0-pyhd8ed1ab_1.conda - sha256: c4b0bdb3d5dee50b60db92f99da3e4c524d5240aafc0a5fcc15e45ae2d1a3cd1 - md5: 46b53236fdd990271b03c3978d4218a9 + size: 38779 + timestamp: 1762509796090 +- conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + sha256: 792da8131b1b53ff667bd6fc617ea9087b570305ccb9913deb36b8e12b3b5141 + md5: 85c4f19f377424eafc4ed7911b291642 depends: - - python >=3.9 + - python >=3.10 - python-dateutil >=2.7.0 - - types-python-dateutil >=2.8.10 + - python-tzdata + - python license: Apache-2.0 - license_family: Apache + license_family: APACHE purls: - pkg:pypi/arrow?source=hash-mapping - size: 99951 - timestamp: 1733584345583 + size: 113854 + timestamp: 1760831179410 - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.0-pyhd8ed1ab_1.conda sha256: 93b14414b3b3ed91e286e1cbe4e7a60c4e1b1c730b0814d1e452a8ac4b9af593 md5: 8f587de4bcf981e26228f268df374a9b @@ -1310,751 +1344,753 @@ packages: - pkg:pypi/async-lru?source=hash-mapping size: 17335 timestamp: 1742153708859 -- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.3.0-pyh71513ae_0.conda - sha256: 99c53ffbcb5dc58084faf18587b215f9ac8ced36bbfb55fa807c00967e419019 - md5: a10d11958cadc13fdb43df75f8b1903f +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyh71513ae_0.conda + sha256: f6c3c19fa599a1a856a88db166c318b148cac3ee4851a9905ed8a04eeec79f45 + md5: c7944d55af26b6d2d7629e27e9a972c1 depends: - - python >=3.9 + - python >=3.10 license: MIT license_family: MIT purls: - pkg:pypi/attrs?source=hash-mapping - size: 57181 - timestamp: 1741918625732 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.0-hbfa7f16_15.conda - sha256: 85086df9b358450196a13fc55bab1c552227df78cafddbe2d15caaea458b41a6 - md5: 16baa9bb7f70a1e457a82023898314a7 + size: 60101 + timestamp: 1759762331492 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.1-h194c533_5.conda + sha256: 7dcbb1eb07158274d7f71377c574bb5f3d2868574f6dcdfcaab4d617deb9f52f + md5: bf0d77362aad67108ea0ace5985807e3 depends: - - libgcc >=13 - __glibc >=2.17,<3.0.a0 - - aws-c-io >=0.20.1,<0.20.2.0a0 - - aws-c-http >=0.10.2,<0.10.3.0a0 + - libgcc >=14 - aws-c-sdkutils >=0.2.4,<0.2.5.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 122993 - timestamp: 1750291448852 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-auth-0.9.0-h11bee3c_15.conda - sha256: 6e5e0eb1bf0f79988ed5d4b5cba474a1b91b1ed4182b4bdcf59b855eb6cc97d6 - md5: 7c61c7ee23ac826b6d6c43ac94b0dec4 + size: 122969 + timestamp: 1762200199500 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-auth-0.9.1-hd76a34f_5.conda + sha256: aed8d62ed0aa84bbf8b964f41be54dbc1202b67a70aa4fd9ec7e37bda913bc29 + md5: 7164f84c1e6ccf7923e8749a26795dba depends: - __osx >=10.13 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-io >=0.20.1,<0.20.2.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 - aws-c-sdkutils >=0.2.4,<0.2.5.0a0 - - aws-c-http >=0.10.2,<0.10.3.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 110566 - timestamp: 1750291407385 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.9.0-hd490b63_15.conda - sha256: 27b1557a502890992950db65ba9414277baec74130042034ba449e71d4b36275 - md5: 41c6aba02d07f6419a01210b5c7398bc + size: 110737 + timestamp: 1762200211142 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.9.1-h179d6b4_5.conda + sha256: bbe1dff32b090d2c2fe366ce2b73182b17576fe0a7f3d7e2f71fa85645b91321 + md5: 58efe2920e5f01319ec65ce981cd41a6 depends: - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - aws-c-io >=0.20.1,<0.20.2.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-http >=0.10.2,<0.10.3.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 - aws-c-sdkutils >=0.2.4,<0.2.5.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 115868 - timestamp: 1750291419402 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.2-h5e3027f_0.conda - sha256: d61cce967e6d97d03aa2828458f7344cdc93422fd2c1126976ab8f475a313363 - md5: 0ead3ab65460d51efb27e5186f50f8e4 + size: 116053 + timestamp: 1762200258493 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.8-h346e085_0.conda + sha256: a2f13bb3da7534a18fb05e5d5de13d3d02fd468aeba0be28147797ef0a1ffce8 + md5: 170690366791b506d48f69f6f0e01bad depends: - __glibc >=2.17,<3.0.a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - libgcc >=13 - - openssl >=3.5.0,<4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - libgcc >=14 + - openssl >=3.5.4,<4.0a0 license: Apache-2.0 license_family: Apache purls: [] - size: 51039 - timestamp: 1749095567725 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-cal-0.9.2-h80a239a_0.conda - sha256: e8f295576194737a48384704aa05a531f174efcf9bb718b18f94d7fdf15508ec - md5: f17aa69cd43527655130be11b92b4318 + size: 55819 + timestamp: 1761947323959 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-cal-0.9.8-h6b06ba2_0.conda + sha256: e2e42469b0152ec3c56f3772fb7fddd162057ae36bc703cdca49ce52d131abfa + md5: 1310b5104c32f0952a1bcd524d398dd4 depends: - __osx >=10.13 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: Apache purls: [] - size: 41080 - timestamp: 1749095748589 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.9.2-hd8a8e38_0.conda - sha256: 49582f0e8f9d0d39532f7c7521ce909679bca765b05fa126c0c5d1419bec5906 - md5: 31e1c0f53295a59e35dfc62ae5299ff4 + size: 44873 + timestamp: 1761947452628 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.9.8-ha82e055_0.conda + sha256: ca4c1693646c9964639e789cc0e451b5cb31d574017b582f5b626ca5b2dde59c + md5: 12a938dc8c890adfc044d7ce3c027e69 depends: - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: Apache purls: [] - size: 48875 - timestamp: 1749095719946 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.3-hb9d3cd8_0.conda - sha256: 251883d45fbc3bc88a8290da073f54eb9d17e8b9edfa464d80cff1b948c571ec - md5: 8448031a22c697fac3ed98d69e8a9160 + size: 53000 + timestamp: 1761947565016 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.5-hb03c661_1.conda + sha256: f5876cc9792346ecdb0326f16f38b2f2fd7b5501228c56419330338fcf37e676 + md5: f1d45413e1c41a7eff162bf702c02cea depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: Apache-2.0 license_family: Apache purls: [] - size: 236494 - timestamp: 1747101172537 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-common-0.12.3-h6e16a3a_0.conda - sha256: 1578b7cdca13d10b6beef3a5db8c4e6d6f21003c303713dfb6219db53a0a88db - md5: bdb14ae9c2ae9f297b71d7e5c78ee3cd + size: 238560 + timestamp: 1762858460824 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-common-0.12.5-h8616949_1.conda + sha256: 0f653e690735c3689ba320812da6981e01e74d26330769726d30c75033efdda1 + md5: 305811c179c589d43cd2cfc9c79e5614 depends: - __osx >=10.13 license: Apache-2.0 license_family: Apache purls: [] - size: 227174 - timestamp: 1747101275434 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.12.3-h2466b09_0.conda - sha256: a9bc739694679ff32fc455a85130e43165a97e64513908ce906f3d7191f11dcf - md5: d6ef6f814f88fcb499c72d194f708a35 + size: 229530 + timestamp: 1762858762807 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.12.5-hfd05255_1.conda + sha256: 87beb42fc12e7f0324d8abd5dd6892f84f82007be09818cad64010df75442e0c + md5: 47ade93c2f58573ad29519ab7be05321 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: Apache purls: [] - size: 235248 - timestamp: 1747101598043 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-hafb2847_5.conda - sha256: 68e7ec0ab4f5973343de089ac71c7b9b9387c35640c61e0236ad45fc3dbfaaaa - md5: e96cc668c0f9478f5771b37d57f90386 + size: 236775 + timestamp: 1762858573513 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h7e655bb_7.conda + sha256: 4bb712dc47f85e0270362fde51ce953803dd2d06526cfb5e56181ec571dcf496 + md5: f175411b6b88db33d1529f7fac572070 depends: + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 21817 - timestamp: 1747144982788 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-compression-0.3.1-hdea44ad_5.conda - sha256: f148c8e7dedd0179424a29765d6dcc9f38071d0582e4da5ce890d1b0fee5ac2d - md5: be47dceb62012ec6fb675fa936c5d3fa + size: 22117 + timestamp: 1761044126699 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-compression-0.3.1-h7df70e9_7.conda + sha256: 9f29b2ca99fd79fdb4fe29ce511431bac708d01b85b10fdade7046339306c0e6 + md5: 6856da211592fa6571a48425f9496068 depends: - __osx >=10.13 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 21283 - timestamp: 1747144985221 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.3.1-h5d0e663_5.conda - sha256: 5f387d438f81047f566112d533c86b04cb7c059bace25df28c0afd72f668d506 - md5: fef493108acbe504dcc49bbf9759ccea + size: 21119 + timestamp: 1761044164764 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.3.1-h83e01e5_7.conda + sha256: d5b71f45edccb3639e2edb8711e0c36bbf32e90e47c16f2715d34cfc155e5b5a + md5: 7112c407057a09c3917d0f6c587a4e4c depends: - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 22690 - timestamp: 1747145057422 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.4-h76f0014_12.conda - sha256: 7b89ed99ac73c863bea4479f1f1af6ce250f9f1722d2804e07cf05d3630c7e08 - md5: f978f2a3032952350d0036c4c4a63bd6 + size: 23116 + timestamp: 1761044168058 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.6-h1deb5b9_4.conda + sha256: ed5131ac1f3f380b2a9f2035a4947e6d96e110bc3d4e24ca12f620e2e861fb07 + md5: 61939d0173b83ed26953e30b5cb37322 depends: - __glibc >=2.17,<3.0.a0 - - libstdcxx >=13 - - libgcc >=13 - - aws-c-io >=0.20.1,<0.20.2.0a0 + - libstdcxx >=14 + - libgcc >=14 + - aws-c-common >=0.12.5,<0.12.6.0a0 - aws-checksums >=0.2.7,<0.2.8.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 57252 - timestamp: 1750287878861 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-event-stream-0.5.4-h01412b5_12.conda - sha256: 28c5b54599b26280614ffb171f2242d351a77c6eb525e9e116359c591dc00d45 - md5: 3d3b8b3c40ad775aa77f5754c62b9026 + size: 58937 + timestamp: 1761592570359 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-event-stream-0.5.6-h0ddc0d0_4.conda + sha256: e6d90f34a16656a638aae92a234c6367136fa71c2bca8dfe78efe56340a0a2a7 + md5: 48b4859b210ec8afbfb3becbae5779fe depends: - - libcxx >=18 + - libcxx >=19 - __osx >=10.13 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 - aws-checksums >=0.2.7,<0.2.8.0a0 - - aws-c-io >=0.20.1,<0.20.2.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 51173 - timestamp: 1750287887384 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-event-stream-0.5.4-ha416645_12.conda - sha256: 89efca036d37a8392f3220ef65e5205f03eae6330dcc121d258b298eae4b2795 - md5: 51269fa3c4b226f6b40aacb72dedb195 + size: 52520 + timestamp: 1761592603978 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-event-stream-0.5.6-hd31a2bc_4.conda + sha256: 0cbe8e72759f5733b13550d261839d6af10ea64059b4ea1d311773e58065ae78 + md5: 60c2a077feedbe83712f0c0fb7d62fee depends: - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - aws-c-io >=0.20.1,<0.20.2.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 - aws-checksums >=0.2.7,<0.2.8.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 55990 - timestamp: 1750287899566 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.2-h015de20_2.conda - sha256: ca0268cead19e985f9b153613f0f6cdb46e0ca32e1647466c506f256269bcdd9 - md5: ad05d594704926ba7c0c894a02ea98f1 + size: 56986 + timestamp: 1761592623586 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-had4b759_1.conda + sha256: 6bb3cb03fddb0010a7e35b2616c34c08cbc601cbe9eebdeaabf47a84b3c2087b + md5: 11b26a1eb8183c11140ca369120bd0c0 depends: + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - aws-c-io >=0.20.1,<0.20.2.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 - aws-c-compression >=0.3.1,<0.3.2.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 223038 - timestamp: 1750289165728 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-http-0.10.2-ha1444c5_2.conda - sha256: 14cd22558beffbecd5ac8626ed362444a7a7b9cd04c1b1f306dbe5a3a4913bab - md5: ea3dff1091a1d30d98bab0bfcd48bb93 + size: 224431 + timestamp: 1762195010218 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-http-0.10.7-ha9fb31a_1.conda + sha256: 152f7c12d13ff2d739099eec96abf27971217c6073d9408c00966b0bac49a074 + md5: 5974a726155a01bfe49c4fc6660c0070 depends: - __osx >=10.13 - - aws-c-io >=0.20.1,<0.20.2.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 - aws-c-compression >=0.3.1,<0.3.2.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 190693 - timestamp: 1750289167421 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.10.2-h81282ae_2.conda - sha256: e01c76ce10e3e8350bdcd1ffcefabf1fa5e170f42e4d654827635d3784fcce27 - md5: 2fa3bbfd5a7e0ac1ec8571c71ca495e2 + size: 192124 + timestamp: 1762195060905 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.10.7-h4b68edd_1.conda + sha256: 6867dbce23fb4c1c7dfbaf2e76f7304b78bde60db7e47bc48b03803e43f5162e + md5: 333509516556c4e41eb8768efc8cb373 depends: - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - aws-c-io >=0.20.1,<0.20.2.0a0 - aws-c-compression >=0.3.1,<0.3.2.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 204438 - timestamp: 1750289208536 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.20.1-hdfce8c9_0.conda - sha256: c6bd4f067a7829795e1c44e4536b71d46f55f69569216aed34a7b375815fa046 - md5: dd2d3530296d75023a19bc9dfb0a1d59 + size: 206692 + timestamp: 1762195079980 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.2-hbff472d_2.conda + sha256: b2df226d99bd4a48228f0cc8acebef6e3912c85709053dacb05136e56cdf8b63 + md5: 4db56ebbdc330e40dbb38e0bd9fb4cad depends: - - libgcc >=13 + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - s2n >=1.5.21,<1.5.22.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - s2n >=1.6.0,<1.6.1.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 179223 - timestamp: 1749844480175 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-io-0.20.1-h550966a_0.conda - sha256: f2eb476b51e71b7dd605bd9a929c5bea3e1b86ae772ce12aa67b896c62674928 - md5: 396e3e79e9ebe9b44a4a9c37bf5a7002 + size: 181061 + timestamp: 1762187768170 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-io-0.23.2-hccfe1ea_2.conda + sha256: 59ff8d1b2ccc542cca62ca4b84f493a9e8b29254a7f73ff0b2238d36e8ebf76a + md5: 84feb49ec906f8dd01b31509252a01c5 depends: - __osx >=10.15 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 181401 - timestamp: 1749844498197 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.20.1-hddf4d6c_0.conda - sha256: f494ad2f99ab6a5b5bec2beb92c914ba2f51c01ffe092f4322c42c5fdafe09fe - md5: 43b20ab02a0ad5a0f2069868579f8f3c + size: 182272 + timestamp: 1762187845153 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.23.2-h460b297_2.conda + sha256: 2f75770819b0b1d363a6bc5adc849a6f31d2456966dd1dfd5a305c15e030892b + md5: 1681fdb54528577c024271355050ab86 depends: - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 179601 - timestamp: 1749844514070 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.1-h1e5e6c0_3.conda - sha256: f9e63492d5dd17f361878ce7efa1878de27225216b4e07990a6cb18c378014dc - md5: d55921ca3469224f689f974278107308 + size: 181738 + timestamp: 1762187804649 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-h8ba2272_8.conda + sha256: 4c745a09b136f6cb3a012cfafd09a98386536dc80f8121d555d990e88481489f + md5: bc8b3533526bf68ed5e6114f63f781ba depends: - - libgcc >=13 + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - aws-c-http >=0.10.2,<0.10.3.0a0 - - aws-c-io >=0.20.1,<0.20.2.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 215867 - timestamp: 1750291920145 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-mqtt-0.13.1-h90c2deb_3.conda - sha256: f19e71095a32f07d597a1f974a682905f2a23b6dfe8903427d2bffe6d47de26c - md5: e4622c9816fa11b03e311bae848e9dd5 + size: 216101 + timestamp: 1762200731083 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-mqtt-0.13.3-ha2a017f_8.conda + sha256: 8f3ed52f53b95fd295e10d3353d3c1ecfd406817fc736ee3e1014703172d59f4 + md5: 63b8a00389c1b40be93805d8882fe28f depends: - __osx >=10.13 - - aws-c-http >=0.10.2,<0.10.3.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-io >=0.20.1,<0.20.2.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 187226 - timestamp: 1750291914810 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-mqtt-0.13.1-h5c1ae27_3.conda - sha256: 6d8ec3659cc03c02ce90e83f0818686f013f3190ec5b82bf5f6c1977902c2c34 - md5: b45b5124b91147887f4670e2e9b017b8 + size: 188001 + timestamp: 1762200790401 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-mqtt-0.13.3-hfde8714_8.conda + sha256: 777a3cc256aed9d5b1c467d608cb74edbd2149175158aa61b55d826e76292c15 + md5: f8e43a779a78ab98d4f1a7d74ed91985 depends: - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - aws-c-io >=0.20.1,<0.20.2.0a0 - - aws-c-http >=0.10.2,<0.10.3.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 206081 - timestamp: 1750291938128 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.8.1-h5e174a9_3.conda - sha256: fb0b8f0b9d2725a9c52501720c276bb42e86f8c6d906c031155a8036a9c93b4b - md5: 02e8cd946bd7f8f13a2569e7ff3d0399 + size: 206354 + timestamp: 1762200772614 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.8.6-h493c25d_7.conda + sha256: eb123f66ad3697be4852c7abdb394a33997aba3d896eb1c6d557e1e42b252c8d + md5: 04f44f1cbc96b225f41852c188f5e8d9 depends: + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - aws-c-io >=0.20.1,<0.20.2.0a0 + - aws-c-auth >=0.9.1,<0.9.2.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 - aws-checksums >=0.2.7,<0.2.8.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 - - openssl >=3.5.0,<4.0a0 - - aws-c-http >=0.10.2,<0.10.3.0a0 - - aws-c-auth >=0.9.0,<0.9.1.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - openssl >=3.5.4,<4.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 133890 - timestamp: 1750296132782 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-s3-0.8.1-hb3f0f26_3.conda - sha256: 09a6033d15b4aba9c6d48d396447380125cb31cf410980b0be3d20645dd0a3e7 - md5: f1b709a82396ea0166e067c927a5a206 + size: 137511 + timestamp: 1762249980464 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-s3-0.8.6-hedfbfa3_7.conda + sha256: be1ffeae554718aa6d508508ba29163ddd01894e4904aebddf0725d6d6e3db77 + md5: cee918c69784859ccf41b30f31871535 depends: - __osx >=10.13 - - aws-c-http >=0.10.2,<0.10.3.0a0 - - aws-c-io >=0.20.1,<0.20.2.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-auth >=0.9.1,<0.9.2.0a0 - aws-checksums >=0.2.7,<0.2.8.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-auth >=0.9.0,<0.9.1.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 120140 - timestamp: 1750296149033 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.8.1-h1e843c7_3.conda - sha256: c2b1e7cbe3e371d1a7f81fe224c5561919f80c61cccc06699f9f9c10f0660079 - md5: e9fadc928f46590181089c114f8cf9c1 + size: 121374 + timestamp: 1762250044623 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.8.6-haf2eb35_7.conda + sha256: fc3a9c80d3757d5f95ea3de8bf068419892d96be2eed5e79cf18b7e1b7e9d3bf + md5: 9ebaacbbb6c60286fa884d51a15604c1 depends: - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - aws-c-auth >=0.9.0,<0.9.1.0a0 - aws-checksums >=0.2.7,<0.2.8.0a0 - - aws-c-io >=0.20.1,<0.20.2.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-http >=0.10.2,<0.10.3.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 + - aws-c-auth >=0.9.1,<0.9.2.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 126859 - timestamp: 1750296162945 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-hafb2847_0.conda - sha256: 18c588c386e21e2a926c6f3c1ba7aaf69059ce1459a134f7c8c1ebfc68cf67ec - md5: 65853df44b7e4029d978c50be888ed89 + size: 129128 + timestamp: 1762250017226 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h7e655bb_2.conda + sha256: 92afcb2bdd1be01c929afc3b1bd05f87a987e3ca31fdec66045b3ed257f7d18a + md5: c82741cfa2c26c27e600694fdf47aa37 depends: + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 59037 - timestamp: 1747308292628 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-sdkutils-0.2.4-hdea44ad_0.conda - sha256: 596ba85d5305c1518275f7cbabe71103c21388b0d679ba3f09f79908e576a651 - md5: cbc6a8a39abc952b9eeb3b61bb6bbb9f + size: 59082 + timestamp: 1761045751420 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-sdkutils-0.2.4-h7df70e9_2.conda + sha256: dfa0dc788fb808609eda0b5b139b7c53762ea1500e0c2d6b7626da6a67b2e7e7 + md5: 6143bef47cb2a462ac8c59c7345f4a8f depends: - __osx >=10.13 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 55445 - timestamp: 1747308295676 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.2.4-h5d0e663_0.conda - sha256: 2d79cca232fe0af6299399b7435620326c9d5b3d3e7f2460d850315d4a83463b - md5: 9c6103d829b015925b2eb2ef148b4519 + size: 55372 + timestamp: 1761046213127 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.2.4-h83e01e5_2.conda + sha256: 66baf285c73ac8f16bd5de4c13f1913dc13a5d8ecf7fc97ed88453d319b0e606 + md5: ac3bdeb8a01e6a4900cf7e9907dc63f2 depends: - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 55722 - timestamp: 1747308370540 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-hafb2847_1.conda - sha256: 03a5e4b3dcda35696133632273043d0b81e55129ff0f9e6d75483aa8eb96371b - md5: 6d28d50637fac4f081a0903b4b33d56d + size: 56441 + timestamp: 1761045782615 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h7e655bb_3.conda + sha256: 65255f3c35f0a22714d13ef4ba91b897fefa1ff7feac3440adc4c9e7715315b5 + md5: 44f8b6b21db8318f1743a28049df4695 depends: - - libgcc >=13 - __glibc >=2.17,<3.0.a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - libgcc >=14 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 76627 - timestamp: 1747141741534 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-checksums-0.2.7-hdea44ad_1.conda - sha256: 68321f03ae4d825b40adb78c2d2cfcef8e78ec64bd54078e60d1d2eefe58b5a1 - md5: 6819ec91b5704e8759f9a533c0a8ac8b + size: 76790 + timestamp: 1761044208107 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-checksums-0.2.7-h7df70e9_3.conda + sha256: 2e0f7e673bda75eaf5670184341fd9baed18fa49b5dcc30c129720bfde65214e + md5: 16741d8bb4a553a20fbd348ae1c24d13 depends: - __osx >=10.13 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 75510 - timestamp: 1747141745458 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.2.7-h5d0e663_1.conda - sha256: ace5e1f7accc03187cd6b507230d0f1e51e03ac86b6f0b2d8213722a2e0dd9dd - md5: 10a0ef46b1cd76a01638b3cd72967d16 + size: 75345 + timestamp: 1761044272151 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.2.7-h83e01e5_3.conda + sha256: d839e97bbab4401dfedaf14df9f6b85437aec764ec930ba37c6934aea42c9182 + md5: 5d04b017f6431cb9742c8629f9e72ebc depends: - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 92710 - timestamp: 1747141831325 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.32.8-ha15c642_6.conda - sha256: 1b8960fe0fe3cb0a8db302c4271061b0d7bbb978e29044c4d07d01fb8ba479dd - md5: d12ed2176be04b85f485c2622c01af12 + size: 93126 + timestamp: 1761044244040 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.0-h719b17a_2.conda + sha256: d34850625fdcbaeda37fd3b83446b71e925463ec79d15ba430636c19526116ed + md5: 2e313660820653ba7557ccbe235b402a depends: - - libstdcxx >=13 - - libgcc >=13 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - aws-c-s3 >=0.8.1,<0.8.2.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-mqtt >=0.13.1,<0.13.2.0a0 - - aws-c-event-stream >=0.5.4,<0.5.5.0a0 - - aws-c-http >=0.10.2,<0.10.3.0a0 - - aws-c-auth >=0.9.0,<0.9.1.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libgcc >=14 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 + - aws-c-mqtt >=0.13.3,<0.13.4.0a0 - aws-c-sdkutils >=0.2.4,<0.2.5.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 - - aws-c-io >=0.20.1,<0.20.2.0a0 + - aws-c-event-stream >=0.5.6,<0.5.7.0a0 + - aws-c-s3 >=0.8.6,<0.8.7.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 + - aws-c-auth >=0.9.1,<0.9.2.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 395108 - timestamp: 1750299573047 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-crt-cpp-0.32.8-h47a58cb_6.conda - sha256: a176799d7d230cd8100ef70d1a530eb5ee96e2e472a2f403a452710098534f04 - md5: cafa9fa0e33a6740fcf8d174e71d77f0 + size: 408300 + timestamp: 1762256210769 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-crt-cpp-0.35.0-h7e7cb56_2.conda + sha256: 12d1fe539258f6e28200d2515f08e7906204c7b2e255a764e7d309ead4a7926c + md5: 9450060dcb26ea7092b57e1625363b63 depends: - __osx >=10.13 - - libcxx >=18 - - aws-c-mqtt >=0.13.1,<0.13.2.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-event-stream >=0.5.4,<0.5.5.0a0 + - libcxx >=19 + - aws-c-mqtt >=0.13.3,<0.13.4.0a0 + - aws-c-auth >=0.9.1,<0.9.2.0a0 - aws-c-sdkutils >=0.2.4,<0.2.5.0a0 - - aws-c-s3 >=0.8.1,<0.8.2.0a0 - - aws-c-http >=0.10.2,<0.10.3.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 - - aws-c-auth >=0.9.0,<0.9.1.0a0 - - aws-c-io >=0.20.1,<0.20.2.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 + - aws-c-s3 >=0.8.6,<0.8.7.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - aws-c-event-stream >=0.5.6,<0.5.7.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 338240 - timestamp: 1750299593931 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-crt-cpp-0.32.8-h5d81255_6.conda - sha256: 0064e94be2f4cd0b9e00bdfaf9f8b08f4aecda01b7659aeea39d95eadc900e5f - md5: 3a86c4830e8997f84ea0c40fcdcc252a + size: 343153 + timestamp: 1762256249379 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-crt-cpp-0.35.0-hd7c148e_2.conda + sha256: d5a9e56d6e442d4296fcccff2e9f61272811537f793d5bc1e7ce738a3fb4b95a + md5: 70b70b882c7951ae908b9cc5cabe00e7 depends: - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - aws-c-http >=0.10.2,<0.10.3.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-mqtt >=0.13.1,<0.13.2.0a0 - - aws-c-auth >=0.9.0,<0.9.1.0a0 + - aws-c-http >=0.10.7,<0.10.8.0a0 + - aws-c-s3 >=0.8.6,<0.8.7.0a0 + - aws-c-auth >=0.9.1,<0.9.2.0a0 + - aws-c-event-stream >=0.5.6,<0.5.7.0a0 + - aws-c-io >=0.23.2,<0.23.3.0a0 + - aws-c-cal >=0.9.8,<0.9.9.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 - aws-c-sdkutils >=0.2.4,<0.2.5.0a0 - - aws-c-io >=0.20.1,<0.20.2.0a0 - - aws-c-event-stream >=0.5.4,<0.5.5.0a0 - - aws-c-s3 >=0.8.1,<0.8.2.0a0 - - aws-c-cal >=0.9.2,<0.9.3.0a0 + - aws-c-mqtt >=0.13.3,<0.13.4.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 294630 - timestamp: 1750299602043 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.510-h4607db7_10.conda - sha256: b340651ca85500d9adc2ac639bc484a500f1ba8eb8a1e8e224799e3f1b4cfca7 - md5: 96f240f245fe2e031ec59dbb3044bd6c + size: 300189 + timestamp: 1762256243536 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h522d481_6.conda + sha256: 36492a2aa10ec63a1f550aa4089b6c9876deced6b3ff4d63689b54f57c545340 + md5: 87a2b0b9822db0ec8bec1c280a8a4443 depends: - - libstdcxx >=13 - - libgcc >=13 + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libcurl >=8.14.0,<9.0a0 - - aws-c-event-stream >=0.5.4,<0.5.5.0a0 + - libstdcxx >=14 + - libgcc >=14 + - aws-c-common >=0.12.5,<0.12.6.0a0 - libzlib >=1.3.1,<2.0a0 - - aws-crt-cpp >=0.32.8,<0.32.9.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 + - aws-crt-cpp >=0.35.0,<0.35.1.0a0 + - libcurl >=8.17.0,<9.0a0 + - aws-c-event-stream >=0.5.6,<0.5.7.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 3401506 - timestamp: 1748938911866 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-sdk-cpp-1.11.510-h894e209_10.conda - sha256: fe9973c8c4498d9341219fa180fae2ed887a7520d3c8e3ff7b1d43f691265f6b - md5: dc3fb705cbb4e44f3236cfaa96be1f2c + size: 3473279 + timestamp: 1762368204170 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-sdk-cpp-1.11.606-hf0dd41a_6.conda + sha256: 8ba6588b51e39ce7f2be3d4d7a3900202c37943a2573185a94ea7d482760d73c + md5: 26442ded3538411891db6cad232e6034 depends: - - libcxx >=18 + - libcxx >=19 - __osx >=10.13 - - libcurl >=8.14.0,<9.0a0 - libzlib >=1.3.1,<2.0a0 - - aws-c-event-stream >=0.5.4,<0.5.5.0a0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-crt-cpp >=0.32.8,<0.32.9.0a0 + - aws-crt-cpp >=0.35.0,<0.35.1.0a0 + - aws-c-event-stream >=0.5.6,<0.5.7.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - libcurl >=8.17.0,<9.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 3255276 - timestamp: 1748938908667 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-sdk-cpp-1.11.510-h7deb975_10.conda - sha256: cd95067d30c6fbe2422110e9571665e29c1f66cab443ef061f40094ef7974e2b - md5: 89c6fd396eba3b89a776a35c11e7d1b9 + size: 3312654 + timestamp: 1762368238720 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-sdk-cpp-1.11.606-h2b076a5_6.conda + sha256: 873b4abda02334fda82e902d744cc76cf8f590c8a5db7fabb178de37bc5fbd4c + md5: f1eace8a769d907f97429433e39d5880 depends: - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - aws-c-common >=0.12.3,<0.12.4.0a0 - - aws-c-event-stream >=0.5.4,<0.5.5.0a0 - - aws-crt-cpp >=0.32.8,<0.32.9.0a0 + - aws-c-event-stream >=0.5.6,<0.5.7.0a0 - libzlib >=1.3.1,<2.0a0 + - aws-c-common >=0.12.5,<0.12.6.0a0 + - aws-crt-cpp >=0.35.0,<0.35.1.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 3222678 - timestamp: 1748939023256 -- conda: https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.14.0-h5cfcd09_0.conda - sha256: fe07debdb089a3db17f40a7f20d283d75284bb4fc269ef727b8ba6fc93f7cb5a - md5: 0a8838771cc2e985cd295e01ae83baf1 + size: 3438258 + timestamp: 1762368263910 +- conda: https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.1-h3a458e0_0.conda + sha256: cba633571e7368953520a4f66dc74c3942cc12f735e0afa8d3d5fc3edf35c866 + md5: 1d4e0d37da5f3c22ecd44033f673feba depends: - __glibc >=2.17,<3.0.a0 - - libcurl >=8.10.1,<9.0a0 - - libgcc >=13 - - libstdcxx >=13 - - openssl >=3.3.2,<4.0a0 + - libcurl >=8.14.1,<9.0a0 + - libgcc >=14 + - libstdcxx >=14 + - openssl >=3.5.4,<4.0a0 license: MIT license_family: MIT purls: [] - size: 345117 - timestamp: 1728053909574 -- conda: https://conda.anaconda.org/conda-forge/osx-64/azure-core-cpp-1.14.0-h9a36307_0.conda - sha256: c7694fc16b9aebeb6ee5e4f80019b477a181d961a3e4d9b6a66b77777eb754fe - md5: 1082a031824b12a2be731d600cfa5ccb + size: 348231 + timestamp: 1760926677260 +- conda: https://conda.anaconda.org/conda-forge/osx-64/azure-core-cpp-1.16.1-he2a98a9_0.conda + sha256: 923a0f9fab0c922e17f8bb27c8210d8978111390ff4e0cf6c1adff3c1a4d13bc + md5: 9f39c22aad61e76bfb73bb7d4114efac depends: - __osx >=10.13 - - libcurl >=8.10.1,<9.0a0 - - libcxx >=17 - - openssl >=3.3.2,<4.0a0 + - libcurl >=8.14.1,<9.0a0 + - libcxx >=19 + - openssl >=3.5.4,<4.0a0 license: MIT license_family: MIT purls: [] - size: 303166 - timestamp: 1728053999891 -- conda: https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.10.0-h113e628_0.conda - sha256: 286b31616c191486626cb49e9ceb5920d29394b9e913c23adb7eb637629ba4de - md5: 73f73f60854f325a55f1d31459f2ab73 + size: 297681 + timestamp: 1760927174036 +- conda: https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.2-h3a5f585_1.conda + sha256: fc1df5ea2595f4f16d0da9f7713ce5fed20cb1bfc7fb098eda7925c7d23f0c45 + md5: 4e921d9c85e6559c60215497978b3cdb depends: - __glibc >=2.17,<3.0.a0 - - azure-core-cpp >=1.14.0,<1.14.1.0a0 - - libgcc >=13 - - libstdcxx >=13 - - openssl >=3.3.2,<4.0a0 + - azure-core-cpp >=1.16.1,<1.16.2.0a0 + - libgcc >=14 + - libstdcxx >=14 + - openssl >=3.5.4,<4.0a0 license: MIT license_family: MIT purls: [] - size: 232351 - timestamp: 1728486729511 -- conda: https://conda.anaconda.org/conda-forge/osx-64/azure-identity-cpp-1.10.0-ha4e2ba9_0.conda - sha256: b9899b9698a6c7353fc5078c449105aae58635d217befbc8ca9d5a527198019b - md5: ad56b6a4b8931d37a2cf5bc724a46f01 + size: 249684 + timestamp: 1761066654684 +- conda: https://conda.anaconda.org/conda-forge/osx-64/azure-identity-cpp-1.13.2-h0e8e1c8_1.conda + sha256: 555e9c9262b996f8c688598760b4cddf4d16ae1cb2f0fd0a31cb76c2fdc7d628 + md5: 32eb613f88ae1530ca78481bdce41cdd depends: - __osx >=10.13 - - azure-core-cpp >=1.14.0,<1.14.1.0a0 - - libcxx >=17 - - openssl >=3.3.2,<4.0a0 + - azure-core-cpp >=1.16.1,<1.16.2.0a0 + - libcxx >=19 + - openssl >=3.5.4,<4.0a0 license: MIT license_family: MIT purls: [] - size: 175344 - timestamp: 1728487066445 -- conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.13.0-h3cf044e_1.conda - sha256: 2606260e5379eed255bcdc6adc39b93fb31477337bcd911c121fc43cd29bf394 - md5: 7eb66060455c7a47d9dcdbfa9f46579b + size: 174582 + timestamp: 1761067038720 +- conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.15.0-h2a74896_1.conda + sha256: 58879f33cd62c30a4d6a19fd5ebc59bd0c4560f575bd02645d93d342b6f881d2 + md5: ffd553ff98ce5d74d3d89ac269153149 depends: - __glibc >=2.17,<3.0.a0 - - azure-core-cpp >=1.14.0,<1.14.1.0a0 - - azure-storage-common-cpp >=12.8.0,<12.8.1.0a0 - - libgcc >=13 - - libstdcxx >=13 + - azure-core-cpp >=1.16.1,<1.16.2.0a0 + - azure-storage-common-cpp >=12.11.0,<12.11.1.0a0 + - libgcc >=14 + - libstdcxx >=14 license: MIT license_family: MIT purls: [] - size: 549342 - timestamp: 1728578123088 -- conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-blobs-cpp-12.13.0-h3d2f5f1_1.conda - sha256: 31984e52450230d04ca98d5232dbe256e5ef6e32b15d46124135c6e64790010d - md5: 3df4fb5d6d0e7b3fb28e071aff23787e + size: 576406 + timestamp: 1761080005291 +- conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-blobs-cpp-12.15.0-h388f2e7_1.conda + sha256: 0a736f04c9778b87884422ebb6b549495430652204d964ff161efb719362baee + md5: 6b5f36e610295f4f859dd9cf680bbf7d depends: - __osx >=10.13 - - azure-core-cpp >=1.14.0,<1.14.1.0a0 - - azure-storage-common-cpp >=12.8.0,<12.8.1.0a0 - - libcxx >=17 + - azure-core-cpp >=1.16.1,<1.16.2.0a0 + - azure-storage-common-cpp >=12.11.0,<12.11.1.0a0 + - libcxx >=19 license: MIT license_family: MIT purls: [] - size: 445040 - timestamp: 1728578180436 -- conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.8.0-h736e048_1.conda - sha256: 273475f002b091b66ce7366da04bf164c3732c03f8692ab2ee2d23335b6a82ba - md5: 13de36be8de3ae3f05ba127631599213 + size: 432811 + timestamp: 1761080273088 +- conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.11.0-h3d7a050_1.conda + sha256: eb590e5c47ee8e6f8cc77e9c759da860ae243eed56aceb67ce51db75f45c9a50 + md5: 89985ba2a3742f34be6aafd6a8f3af8c depends: - __glibc >=2.17,<3.0.a0 - - azure-core-cpp >=1.14.0,<1.14.1.0a0 - - libgcc >=13 - - libstdcxx >=13 - - libxml2 >=2.12.7,<2.14.0a0 - - openssl >=3.3.2,<4.0a0 + - azure-core-cpp >=1.16.1,<1.16.2.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libxml2 + - libxml2-16 >=2.14.6 + - openssl >=3.5.4,<4.0a0 license: MIT license_family: MIT purls: [] - size: 149312 - timestamp: 1728563338704 -- conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-common-cpp-12.8.0-h1ccc5ac_1.conda - sha256: 51fb67d2991d105b8f7b97b4810cd63bac4dc421a4a9c83c15a98ca520a42e1e - md5: 5b3e79eb148d6e30d6c697788bad9960 + size: 149620 + timestamp: 1761066643066 +- conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-common-cpp-12.11.0-h56a711b_1.conda + sha256: 322919e9842ddf5c9d0286667420a76774e1e42ae0520445d65726f8a2565823 + md5: 278ccb9a3616d4342731130287c3ba79 depends: - __osx >=10.13 - - azure-core-cpp >=1.14.0,<1.14.1.0a0 - - libcxx >=17 - - libxml2 >=2.12.7,<2.14.0a0 - - openssl >=3.3.2,<4.0a0 + - azure-core-cpp >=1.16.1,<1.16.2.0a0 + - libcxx >=19 + - libxml2 + - libxml2-16 >=2.14.6 + - openssl >=3.5.4,<4.0a0 license: MIT license_family: MIT purls: [] - size: 126229 - timestamp: 1728563580392 -- conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.12.0-ha633028_1.conda - sha256: 5371e4f3f920933bb89b926a85a67f24388227419abd6e99f6086481e5e8d5f2 - md5: 7c1980f89dd41b097549782121a73490 + size: 126230 + timestamp: 1761066840950 +- conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.13.0-hf38f1be_1.conda + sha256: 9f3d0f484e97cef5f019b7faef0c07fb7ee6c584e3a6e2954980f440978a365e + md5: f10b9303c7239fbce3580a60a92bcf97 depends: - __glibc >=2.17,<3.0.a0 - - azure-core-cpp >=1.14.0,<1.14.1.0a0 - - azure-storage-blobs-cpp >=12.13.0,<12.13.1.0a0 - - azure-storage-common-cpp >=12.8.0,<12.8.1.0a0 - - libgcc >=13 - - libstdcxx >=13 + - azure-core-cpp >=1.16.1,<1.16.2.0a0 + - azure-storage-blobs-cpp >=12.15.0,<12.15.1.0a0 + - azure-storage-common-cpp >=12.11.0,<12.11.1.0a0 + - libgcc >=14 + - libstdcxx >=14 license: MIT license_family: MIT purls: [] - size: 287366 - timestamp: 1728729530295 -- conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-files-datalake-cpp-12.12.0-h86941f0_1.conda - sha256: 12d95251a8793ea2e78f494e69353a930e9ea06bbaaaa4ccb6e5b3e35ee0744f - md5: 60452336e7f61f6fdaaff69264ee112e + size: 299198 + timestamp: 1761094654852 +- conda: https://conda.anaconda.org/conda-forge/osx-64/azure-storage-files-datalake-cpp-12.13.0-h1984e67_1.conda + sha256: 268175ab07f1917eff35e4c38a17a2b71c5f9b86e38e5c0b313da477600a82df + md5: ef5701f2da108d432e7872d58e8ac64e depends: - __osx >=10.13 - - azure-core-cpp >=1.14.0,<1.14.1.0a0 - - azure-storage-blobs-cpp >=12.13.0,<12.13.1.0a0 - - azure-storage-common-cpp >=12.8.0,<12.8.1.0a0 - - libcxx >=17 + - azure-core-cpp >=1.16.1,<1.16.2.0a0 + - azure-storage-blobs-cpp >=12.15.0,<12.15.1.0a0 + - azure-storage-common-cpp >=12.11.0,<12.11.1.0a0 + - libcxx >=19 license: MIT license_family: MIT purls: [] - size: 200991 - timestamp: 1728729588371 + size: 203298 + timestamp: 1761095036240 - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda sha256: 1c656a35800b7f57f7371605bc6507c8d3ad60fbaaec65876fce7f73df1fc8ac md5: 0a01c169f0ab0f91b26e77a3301fbfe4 @@ -2064,7 +2100,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/babel?source=compressed-mapping + - pkg:pypi/babel?source=hash-mapping size: 6938256 timestamp: 1738490268466 - conda: https://conda.anaconda.org/conda-forge/noarch/backports-1.0-pyhd8ed1ab_5.conda @@ -2100,19 +2136,36 @@ packages: - pkg:pypi/backrefs?source=hash-mapping size: 143810 timestamp: 1740887689966 -- conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.13.4-pyha770c72_0.conda - sha256: ddb0df12fd30b2d36272f5daf6b6251c7625d6a99414d7ea930005bbaecad06d - md5: 9f07c4fc992adb2d6c30da7fab3959a7 +- conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda + sha256: b949bd0121bb1eabc282c4de0551cc162b621582ee12b415e6f8297398e3b3b4 + md5: 749ebebabc2cae99b2e5b3edd04c6ca2 depends: - - python >=3.9 + - python >=3.10 - soupsieve >=1.2 - typing-extensions license: MIT license_family: MIT purls: - - pkg:pypi/beautifulsoup4?source=compressed-mapping - size: 146613 - timestamp: 1744783307123 + - pkg:pypi/beautifulsoup4?source=hash-mapping + size: 89146 + timestamp: 1759146127397 +- conda: https://conda.anaconda.org/conda-forge/linux-64/black-25.1.0-py313h78bf25f_0.conda + sha256: f6b6e2e529fbac828c9cb630f09333a66749dab5291aa067407ba2593689d2d7 + md5: 9ea587916fdf7b23e723e428f02c1bb5 + depends: + - click >=8.0.0 + - mypy_extensions >=0.4.3 + - packaging >=22.0 + - pathspec >=0.9 + - platformdirs >=2 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/black?source=hash-mapping + size: 398823 + timestamp: 1738616111923 - conda: https://conda.anaconda.org/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda sha256: c68f110cd491dc839a69e340930862e54c00fb02cede5f1831fcf8a253bd68d2 md5: b9b0c42e7316aa6043bdfd49883955b8 @@ -2153,9 +2206,9 @@ packages: purls: [] size: 4213 timestamp: 1737382993425 -- conda: https://conda.anaconda.org/conda-forge/noarch/bokeh-3.7.3-pyhd8ed1ab_0.conda - sha256: dd116a77a5aca118cfdfcc97553642295a3fb176a4e741fd3d1363ee81cebdfd - md5: 708d2f99b8a2c833ff164a225a265e76 +- conda: https://conda.anaconda.org/conda-forge/noarch/bokeh-3.8.1-pyhd8ed1ab_0.conda + sha256: f76ff3ce23987f68f1a09ce9f56c81a417e47826a1beb34fdc121a452edd9df8 + md5: f301f72474b91f1f83d42bcc7d81ce09 depends: - contourpy >=1.2 - jinja2 >=2.9 @@ -2171,104 +2224,104 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/bokeh?source=hash-mapping - size: 4934851 - timestamp: 1747091638593 -- conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.1-pyhd8ed1ab_0.conda - sha256: 38de10b8608ed962ad3e01d6ddc5cfa373221cfdc0faa96a46765d6defffc75f - md5: 9f3937b768675ab4346f07e9ef723e4b + - pkg:pypi/bokeh?source=compressed-mapping + size: 5027028 + timestamp: 1762557204752 +- conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda + sha256: 1acf87c77d920edd098ddc91fa785efc10de871465dee0f463815b176e019e8b + md5: 1fcdf88e7a8c296d3df8409bf0690db4 depends: - jinja2 >=3 - - python >=3.9 + - python >=3.10 license: MIT license_family: MIT purls: - pkg:pypi/branca?source=hash-mapping - size: 29601 - timestamp: 1734433493998 -- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py313h46c70d0_3.conda - sha256: e510ad1db7ea882505712e815ff02514490560fd74b5ec3a45a6c7cf438f754d - md5: 2babfedd9588ad40c7113ddfe6a5ca82 + size: 30176 + timestamp: 1759755695447 +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313h09d1b84_0.conda + sha256: 93eeadb5ef4ae211edb01f4a4d837e4b5ceba8ddaefdd68a0c982503c8cc86d1 + md5: dfd94363b679c74937b3926731ee861a depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 + - libgcc >=14 + - libstdcxx >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 constrains: - - libbrotlicommon 1.1.0 hb9d3cd8_3 + - libbrotlicommon 1.2.0 h09219d5_0 license: MIT license_family: MIT purls: - pkg:pypi/brotli?source=hash-mapping - size: 350295 - timestamp: 1749230225293 -- conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.1.0-py313h14b76d3_3.conda - sha256: b486b5d469bd412fcf5a49d50056a069d84d44f0762b64e18f5a3027b1871278 - md5: b48636a1c2074e650b7a930e3a68f104 + size: 367767 + timestamp: 1761592405814 +- conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.2.0-py313hd4eab94_0.conda + sha256: a70711b223c82d92ec9edd8cfef4305d803331d46b0ef48e55a4d63e124c9a0d + md5: ece2240943077fc695e29eb4e5596c77 depends: - __osx >=10.13 - - libcxx >=18 + - libcxx >=19 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 constrains: - - libbrotlicommon 1.1.0 h6e16a3a_3 + - libbrotlicommon 1.2.0 h105ed1c_0 license: MIT license_family: MIT purls: - pkg:pypi/brotli?source=hash-mapping - size: 366909 - timestamp: 1749230725855 -- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.1.0-py313h5813708_3.conda - sha256: 152e1f4bb8076b4f37a70e80dcd457a50e14e0bd5501351cd0fc602c5ef782a5 - md5: a25f98cfd4eb1ac26325c1869f11edf5 + size: 390098 + timestamp: 1761593175378 +- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313hf510273_0.conda + sha256: 29020d8d62652cdd1c841c4b23563efc2558dc6b97e272f63ee6731e0513df94 + md5: 7cdbffd86ca06b75fee15d2762b3616d depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - - libbrotlicommon 1.1.0 h2466b09_3 + - libbrotlicommon 1.2.0 hc82b238_0 license: MIT license_family: MIT purls: - - pkg:pypi/brotli?source=compressed-mapping - size: 321652 - timestamp: 1749231335599 -- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - sha256: 5ced96500d945fb286c9c838e54fa759aa04a7129c59800f0846b4335cee770d - md5: 62ee74e96c5ebb0af99386de58cf9553 + - pkg:pypi/brotli?source=hash-mapping + size: 335623 + timestamp: 1761592891692 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + sha256: c30daba32ddebbb7ded490f0e371eae90f51e72db620554089103b4a6934b0d5 + md5: 51a19bba1b8ebfb60df25cde030b7ebc depends: - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 + - libgcc >=14 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 252783 - timestamp: 1720974456583 -- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda - sha256: cad153608b81fb24fc8c509357daa9ae4e49dfc535b2cb49b91e23dbd68fc3c5 - md5: 7ed4301d437b59045be7e051a0308211 + size: 260341 + timestamp: 1757437258798 +- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda + sha256: 8f50b58efb29c710f3cecf2027a8d7325ba769ab10c746eff75cea3ac050b10c + md5: 97c4b3bd8a90722104798175a1bdddbf depends: - __osx >=10.13 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 134188 - timestamp: 1720974491916 -- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda - sha256: 35a5dad92e88fdd7fc405e864ec239486f4f31eec229e31686e61a140a8e573b - md5: 276e7ffe9ffe39688abc665ef0f45596 + size: 132607 + timestamp: 1757437730085 +- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda + sha256: d882712855624641f48aa9dc3f5feea2ed6b4e6004585d3616386a18186fe692 + md5: 1077e9333c41ff0be8edd1a5ec0ddace depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 54927 - timestamp: 1720974860185 + size: 55977 + timestamp: 1757437738856 - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda sha256: f8003bef369f57396593ccd03d08a8e21966157269426f71e943f96e4b579aeb md5: f7f0d6cc2dc986d42ac2689ec88192be @@ -2302,24 +2355,24 @@ packages: purls: [] size: 194147 timestamp: 1744128507613 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.6.15-h4c7d964_0.conda - sha256: 065241ba03ef3ee8200084c075cbff50955a7e711765395ff34876dbc51a6bb9 - md5: b01649832f7bc7ff94f8df8bd2ee6457 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-h4c7d964_0.conda + sha256: bfb7f9f242f441fdcd80f1199edd2ecf09acea0f2bcef6f07d7cbb1a8131a345 + md5: e54200a1cd1fe33d61c9df8d3b00b743 depends: - __win license: ISC purls: [] - size: 151351 - timestamp: 1749990170707 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.6.15-hbd8a1cb_0.conda - sha256: 7cfec9804c84844ea544d98bda1d9121672b66ff7149141b8415ca42dfcd44f6 - md5: 72525f07d72806e3b639ad4504c30ce5 + size: 156354 + timestamp: 1759649104842 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda + sha256: 3b5ad78b8bb61b6cdc0978a6a99f8dfb2cc789a451378d054698441005ecbdb6 + md5: f9e5fbc24009179e8b0409624691758a depends: - __unix license: ISC purls: [] - size: 151069 - timestamp: 1749990087500 + size: 155907 + timestamp: 1759649036195 - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 noarch: python sha256: 561e6660f26c35d137ee150187d89767c988413c978e1b712d53f27ddf70ea17 @@ -2342,89 +2395,89 @@ packages: - pkg:pypi/cached-property?source=hash-mapping size: 11065 timestamp: 1615209567874 -- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.6.15-pyhd8ed1ab_0.conda - sha256: d71c85835813072cd6d7ce4b24be34215cd90c104785b15a5d58f4cd0cb50778 - md5: 781d068df0cc2407d4db0ecfbb29225b +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda + sha256: 955bac31be82592093f6bc006e09822cd13daf52b28643c9a6abd38cd5f4a306 + md5: 257ae203f1d204107ba389607d375ded depends: - - python >=3.9 + - python >=3.10 license: ISC purls: - pkg:pypi/certifi?source=hash-mapping - size: 155377 - timestamp: 1749972291158 -- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py313hfab6e84_0.conda - sha256: 73cd6199b143a8a6cbf733ce124ed57defc1b9a7eab9b10fd437448caf8eaa45 - md5: ce6386a5892ef686d6d680c345c40ad1 + size: 160248 + timestamp: 1759648987029 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda + sha256: 2162a91819945c826c6ef5efe379e88b1df0fe9a387eeba23ddcf7ebeacd5bd6 + md5: d0616e7935acab407d1543b28c446f6f depends: - __glibc >=2.17,<3.0.a0 - - libffi >=3.4,<4.0a0 - - libgcc >=13 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 - pycparser - - python >=3.13.0rc1,<3.14.0a0 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: MIT license_family: MIT purls: - pkg:pypi/cffi?source=hash-mapping - size: 295514 - timestamp: 1725560706794 -- conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.17.1-py313h49682b3_0.conda - sha256: 660c8f8488f78c500a1bb4a803c31403104b1ee2cabf1476a222a3b8abf5a4d7 - md5: 98afc301e6601a3480f9e0b9f8867ee0 + size: 298357 + timestamp: 1761202966461 +- conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-2.0.0-py313hf57695f_1.conda + sha256: 16c8c80bebe1c3d671382a64beaa16996e632f5b75963379e2b084eb6bc02053 + md5: b10f64f2e725afc9bf2d9b30eff6d0ea depends: - __osx >=10.13 - - libffi >=3.4,<4.0a0 + - libffi >=3.5.2,<3.6.0a0 - pycparser - - python >=3.13.0rc1,<3.14.0a0 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: MIT license_family: MIT purls: - pkg:pypi/cffi?source=hash-mapping - size: 284540 - timestamp: 1725560667915 -- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-1.17.1-py313ha7868ed_0.conda - sha256: b19f581fe423858f1f477c52e10978be324c55ebf2e418308d30d013f4a476ff - md5: 519a29d7ac273f8c165efc0af099da42 + size: 290946 + timestamp: 1761203173891 +- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda + sha256: f867a11f42bb64a09b232e3decf10f8a8fe5194d7e3a216c6bac9f40483bd1c6 + md5: 55b44664f66a2caf584d72196aa98af9 depends: - pycparser - - python >=3.13.0rc1,<3.14.0a0 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: - pkg:pypi/cffi?source=hash-mapping - size: 291828 - timestamp: 1725561211547 -- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - sha256: 535ae5dcda8022e31c6dc063eb344c80804c537a5a04afba43a845fa6fa130f5 - md5: 40fe4284b8b5835a9073a645139f35af + size: 292681 + timestamp: 1761203203673 +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda + sha256: b32f8362e885f1b8417bac2b3da4db7323faa12d5db62b7fd6691c02d60d6f59 + md5: a22d1fd9bf98827e280a02875d9a007a depends: - - python >=3.9 + - python >=3.10 license: MIT license_family: MIT purls: - pkg:pypi/charset-normalizer?source=hash-mapping - size: 50481 - timestamp: 1746214981991 -- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda - sha256: 8aee789c82d8fdd997840c952a586db63c6890b00e88c4fb6e80a38edd5f51c0 - md5: 94b550b8d3a614dbd326af798c7dfb40 + size: 50965 + timestamp: 1760437331772 +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda + sha256: c6567ebc27c4c071a353acaf93eb82bb6d9a6961e40692a359045a89a61d02c0 + md5: e76c4ba9e1837847679421b8d549b784 depends: - __unix - python >=3.10 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/click?source=hash-mapping - size: 87749 - timestamp: 1747811451319 -- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh7428d3b_0.conda - sha256: 20c2d8ea3d800485245b586a28985cba281dd6761113a49d7576f6db92a0a891 - md5: 3a59475037bc09da916e4062c5cad771 + - pkg:pypi/click?source=compressed-mapping + size: 91622 + timestamp: 1758270534287 +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh7428d3b_0.conda + sha256: 0a008359973e833b568d0a18cf04556b12a4f5182e745dfc8ade32c38fa1fca5 + md5: 4601476ee4ad7ad522e5ffa5a579a48e depends: - __win - colorama @@ -2432,20 +2485,20 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/click?source=compressed-mapping - size: 88117 - timestamp: 1747811467132 -- conda: https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.1-pyhd8ed1ab_0.conda - sha256: 21ecead7268241007bf65691610cd7314da68c1f88113092af690203b5780db5 - md5: 364ba6c9fb03886ac979b482f39ebb92 + - pkg:pypi/click?source=hash-mapping + size: 92148 + timestamp: 1758270588199 +- conda: https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.2-pyhd8ed1ab_0.conda + sha256: 57050bd1bbac9e4be3728da4d33dee2168884d61d0ec51cd2ac72a1b34e11fc3 + md5: fcac5929097ba1f2a0e5b6ecaa13b253 depends: - - python >=3.9 + - python >=3.10 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/cloudpickle?source=hash-mapping - size: 25870 - timestamp: 1736947650712 + - pkg:pypi/cloudpickle?source=compressed-mapping + size: 26621 + timestamp: 1762167702602 - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287 md5: 962b9857ee8e7018c22f2776ffa0b2d7 @@ -2457,171 +2510,165 @@ packages: - pkg:pypi/colorama?source=hash-mapping size: 27011 timestamp: 1733218222191 -- conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.2-pyhd8ed1ab_1.conda - sha256: 7e87ef7c91574d9fac19faedaaee328a70f718c9b4ddadfdc0ba9ac021bd64af - md5: 74673132601ec2b7fc592755605f4c1b +- conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + sha256: 576a44729314ad9e4e5ebe055fbf48beb8116b60e58f9070278985b2b634f212 + md5: 2da13f2b299d8e1995bafbbe9689a2f7 depends: - python >=3.9 - - traitlets >=5.3 + - python license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/comm?source=hash-mapping - size: 12103 - timestamp: 1733503053903 -- conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py313h33d0bda_0.conda - sha256: 8e6e7c9644fa4841909f46b8136b6fad540c9c7b2688bfc15e8f9ce5eef0aabe - md5: 5dc81fffe102f63045225007a33d6199 + size: 14690 + timestamp: 1753453984907 +- conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3.conda + sha256: c545751fd48f119f2c28635514e6aa6ae784d9a1d4eb0e10be16c776e961f333 + md5: 6186382cb34a9953bf2a18fc763dc346 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - - numpy >=1.23 + - libgcc >=14 + - libstdcxx >=14 + - numpy >=1.25 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause - license_family: BSD purls: - - pkg:pypi/contourpy?source=hash-mapping - size: 278576 - timestamp: 1744743243839 -- conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.2-py313ha0b1807_0.conda - sha256: 1aae5a85b7fce44717c77a4f59d465b375ccba7b73cca8500a241acd8f6afe2d - md5: 2c2d1f840df1c512b34e0537ef928169 + - pkg:pypi/contourpy?source=compressed-mapping + size: 297459 + timestamp: 1762525479137 +- conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py313h5eff275_3.conda + sha256: a173a39f85997a2d77910a4f92d39baaf5ce2b3c86cff94e67a5a920d7d39e00 + md5: 76be023d05c67d445a0d0591fcdb83a6 depends: - __osx >=10.13 - - libcxx >=18 - - numpy >=1.23 + - libcxx >=19 + - numpy >=1.25 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause - license_family: BSD purls: - pkg:pypi/contourpy?source=hash-mapping - size: 256791 - timestamp: 1744743360600 -- conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py313h1ec8472_0.conda - sha256: e791b7cce4c7e1382140e7c542d0436ce78a605504b23f6f33c6c0f0cd01e9f2 - md5: 5cc68b7c893d2e3b9d838ef3b8716862 + size: 270248 + timestamp: 1762525788641 +- conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py313hf069bd2_3.conda + sha256: f5acc168a1f5eedd159bd1a89dc1dd4d901dc0502b769b4fca2bc5bdb4293fcf + md5: a1d5292683730418cd19b6e0cefcfc76 depends: - - numpy >=1.23 + - numpy >=1.25 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: BSD-3-Clause - license_family: BSD purls: - - pkg:pypi/contourpy?source=hash-mapping - size: 217972 - timestamp: 1744743864955 -- conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.9.1-py313h8060acc_0.conda - sha256: 876bb057fb7c40322471d0e65c8d149512991b89b7c1dfac92b59a9fe2a318f9 - md5: 5e959c405af6d6b603810fdf12b6f191 + - pkg:pypi/contourpy?source=compressed-mapping + size: 225553 + timestamp: 1762525633181 +- conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.11.3-py313h3dea7bd_0.conda + sha256: d3405b1c97311d61cbe3fb9974be5debc1c070240c903d16104bf4ccc153941f + md5: 9072bbff6c9745c25ab14d04c272633c depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - tomli license: Apache-2.0 - license_family: APACHE purls: - - pkg:pypi/coverage?source=hash-mapping - size: 381728 - timestamp: 1749833700835 -- conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.9.1-py313h717bdf5_0.conda - sha256: 7bc7f5e6017f34c3acefba80c0cc0179de35539e1858a70d1aa54b92f0f0af23 - md5: dc9348f206ef595c238e426ba1a61503 + - pkg:pypi/coverage?source=compressed-mapping + size: 386073 + timestamp: 1762739217751 +- conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.11.3-py313h0f4d31d_0.conda + sha256: 9c512c09b9f3ef76018d27f3efa8c269b491683812e7042464c5b0effc2f722d + md5: 0dbf654f1afe575cb6c04775daeedb2b depends: - __osx >=10.13 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - tomli license: Apache-2.0 - license_family: APACHE purls: - pkg:pypi/coverage?source=hash-mapping - size: 379153 - timestamp: 1749833527306 -- conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.9.1-py313hb4c8b1a_0.conda - sha256: d58320b827b6428d090d966f40802a3793d10b0e6b79f5e116c98421a4365735 - md5: 1c4e3215bb5f74caf6653bb802d3fc02 + size: 386157 + timestamp: 1762739250586 +- conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.11.3-py313hd650c13_0.conda + sha256: 4970f139c13b5a3f2aa731bd6ce95447ae7190197f4ab279131c4fb0b3ca4ba7 + md5: b83dee6985f407115e912e31ddb78f3e depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - tomli - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 - license_family: APACHE purls: - pkg:pypi/coverage?source=hash-mapping - size: 405028 - timestamp: 1749833588845 -- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.5-py313hd8ed1ab_102.conda + size: 414641 + timestamp: 1762739362949 +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda noarch: generic - sha256: 058c8156ff880b1180a36b94307baad91f9130d0e3019ad8c7ade035852016fb - md5: 0401f31e3c9e48cebf215472aa3e7104 + sha256: 31da683e8a15e2062adfb29c9fb23d4253550a0b3c9be1cd45530f88796b4644 + md5: 367133808e89325690562099851529c8 depends: - python >=3.13,<3.14.0a0 - python_abi * *_cp313 license: Python-2.0 purls: [] - size: 47560 - timestamp: 1750062514868 -- conda: https://conda.anaconda.org/conda-forge/linux-64/crc32c-2.7.1-py313h536fd9c_1.conda - sha256: 8149dbd6ff322e55ca834d4d1e4014895d77ba666eeb04a636421049e399f5c6 - md5: ce5366b582bb63422533746dfc5b8bb6 + size: 48397 + timestamp: 1761175097707 +- conda: https://conda.anaconda.org/conda-forge/linux-64/crc32c-2.8-py313h54dd161_1.conda + sha256: 27453f3db7bdab1484ea01911732b80533a7f648c0796761b1b92fa0e084f90f + md5: d43aac202130fc99f51f1b829fb8398d depends: + - python - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - python >=3.13,<3.14.0a0 + - libgcc >=14 - python_abi 3.13.* *_cp313 license: LGPL-2.1-or-later - license_family: LGPL purls: - pkg:pypi/crc32c?source=hash-mapping - size: 49721 - timestamp: 1741391740851 -- conda: https://conda.anaconda.org/conda-forge/osx-64/crc32c-2.7.1-py313h63b0ddb_1.conda - sha256: 5f7856c199a8db60eb70280961453baa2194bd66febab97201eb0ff2823dbe4c - md5: 6aed32017e67144b86aafc5ad80a6e99 + size: 76113 + timestamp: 1762474361885 +- conda: https://conda.anaconda.org/conda-forge/osx-64/crc32c-2.8-py313hcb05632_1.conda + sha256: 32358b1eaee68e888198b0ccc4a53718c1db52d10725842ffa1827ffee73bc73 + md5: 61861a2313718eff5a47ef2e4a595a1b depends: + - python - __osx >=10.13 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: LGPL-2.1-or-later - license_family: LGPL purls: - pkg:pypi/crc32c?source=hash-mapping - size: 48759 - timestamp: 1741391762632 -- conda: https://conda.anaconda.org/conda-forge/win-64/crc32c-2.7.1-py313ha7868ed_1.conda - sha256: 024667075d8cf272f904f4585de123d26be43eeac6f8d5355535327fc7c03f29 - md5: 6c87fea5f1b4fe2650e265372e60813b + size: 74996 + timestamp: 1762474207999 +- conda: https://conda.anaconda.org/conda-forge/win-64/crc32c-2.8-py313h5fd188c_1.conda + sha256: f437d16a127cd6bda9a08c5eb8e4fef66528a70506e885c10fef9566fd67a744 + md5: 73e6bee9dfbc65d4869b32eb11ddcf66 depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 license: LGPL-2.1-or-later - license_family: LGPL purls: - pkg:pypi/crc32c?source=hash-mapping - size: 52709 - timestamp: 1741392087715 -- conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-45.0.4-py313h6556f6e_0.conda - sha256: e086e42bda38fcc224a13d4fff098992aab24354834c26da1d088d11d82e9a42 - md5: 48fe3ecda5de1fc0362a0821f6ba2378 + size: 137184 + timestamp: 1762474092192 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-46.0.3-py313hafb0bba_0.conda + sha256: 975cea9e12c4afdb8e12373cab92569fe4062bb0b5b3c39ee7c077c9fdca4121 + md5: 524ddf173d159040f9a4e2de23e08085 depends: - __glibc >=2.17,<3.0.a0 - - cffi >=1.12 - - libgcc >=13 - - openssl >=3.5.0,<4.0a0 + - cffi >=1.14 + - libgcc >=14 + - openssl >=3.5.4,<4.0a0 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 constrains: @@ -2630,8 +2677,8 @@ packages: license_family: BSD purls: - pkg:pypi/cryptography?source=hash-mapping - size: 1664068 - timestamp: 1749539269244 + size: 1718808 + timestamp: 1760605188769 - pypi: ../eozilla/cuiman name: cuiman version: 0.0.8 @@ -2647,12 +2694,12 @@ packages: - gavicore>=0.0.7 requires_python: '>=3.10' editable: true -- conda: https://conda.anaconda.org/conda-forge/linux-64/cytoolz-1.0.1-py313h536fd9c_0.conda - sha256: 4ed6220a9db0c0fbef44b0b6c642e8f20e4d60a52628fc4d995f8c0db5ad942e - md5: e886bb6a3c24f8b9dd4fcd1d617a1f64 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cytoolz-1.1.0-py313h07c4f96_1.conda + sha256: a8ffc7cf31a698a57a46bf7977185ed1e644c5e35d4e166d8f260dca93af6ffb + md5: bcca9afd203fe05d9582249ac12762da depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - toolz >=0.10.0 @@ -2660,11 +2707,11 @@ packages: license_family: BSD purls: - pkg:pypi/cytoolz?source=hash-mapping - size: 388205 - timestamp: 1734107369698 -- conda: https://conda.anaconda.org/conda-forge/osx-64/cytoolz-1.0.1-py313h63b0ddb_0.conda - sha256: 7f33240c0b9f6d5fd7f702ad832d0ebd0cd896fe283cb579b313b50e2a70f8db - md5: 863bfeda5c2c1ff534034b3a0f290297 + size: 590435 + timestamp: 1760905824293 +- conda: https://conda.anaconda.org/conda-forge/osx-64/cytoolz-1.1.0-py313hf050af9_1.conda + sha256: e2458af0964417f6ca0be05a82af20647c632362cc319c7a29eb268cef28e897 + md5: 9eb5b350c5a60139b32c72bf8695139c depends: - __osx >=10.13 - python >=3.13,<3.14.0a0 @@ -2674,69 +2721,69 @@ packages: license_family: BSD purls: - pkg:pypi/cytoolz?source=hash-mapping - size: 339139 - timestamp: 1734107540979 -- conda: https://conda.anaconda.org/conda-forge/win-64/cytoolz-1.0.1-py313ha7868ed_0.conda - sha256: 277d5b23f52e02453e9dab28e9335caa16fcaa54bb4e7dd771a86d3c95e580a5 - md5: a66eb40fddbf2a2e64b8e4c7128ff1db + size: 555864 + timestamp: 1760906288247 +- conda: https://conda.anaconda.org/conda-forge/win-64/cytoolz-1.1.0-py313h5ea7bf4_1.conda + sha256: 3c1e0e7a7d648532e8df97b7fe7b821460eab4011c163e4db686ee8d37db1126 + md5: ef2e9ff6d43a07587e3483c34adf6cff depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - toolz >=0.10.0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/cytoolz?source=hash-mapping - size: 315372 - timestamp: 1734107736055 -- conda: https://conda.anaconda.org/conda-forge/noarch/dask-2025.5.1-pyhd8ed1ab_0.conda - sha256: 6c01513d621c492fb414f8c498bcd84c649025ed159f3042378101822f17c22b - md5: 97ee3885b8de1d729c40f28c2dddb335 + size: 521155 + timestamp: 1760906037897 +- conda: https://conda.anaconda.org/conda-forge/noarch/dask-2025.11.0-pyhcf101f3_0.conda + sha256: 8c4b681857ea44f4a299997a024509c21b1c054bbc0335ad82cc1bbfef4a8880 + md5: 1f97a470dbcf4a633e8da14e08428d42 depends: - - bokeh >=3.1.0 + - python >=3.10 + - dask-core >=2025.11.0,<2025.11.1.0a0 + - distributed >=2025.11.0,<2025.11.1.0a0 - cytoolz >=0.11.0 - - dask-core >=2025.5.1,<2025.5.2.0a0 - - distributed >=2025.5.1,<2025.5.2.0a0 - - jinja2 >=2.10.3 - lz4 >=4.3.2 - numpy >=1.24 - pandas >=2.0 + - bokeh >=3.1.0 + - jinja2 >=2.10.3 - pyarrow >=14.0.1 - - python >=3.10 + - python constrains: - openssl !=1.1.1e license: BSD-3-Clause - license_family: BSD purls: [] - size: 8024 - timestamp: 1747777430676 -- conda: https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.5.1-pyhd8ed1ab_0.conda - sha256: 993fe9ff727441c57fab9969c61eb04eeca2ca82cce432804798f258177ab419 - md5: 8f0ef561cd615a17df3256742a3457c4 + size: 11723 + timestamp: 1762461029811 +- conda: https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.11.0-pyhcf101f3_0.conda + sha256: a1fa1457cf759d90deb87c258da393809285b807ecef47a317d210fa4fa9f7fb + md5: 91549f296c15ef7b49ee6600e7c934c1 depends: + - python >=3.10 - click >=8.1 - cloudpickle >=3.0.0 - - fsspec >=2021.09.0 - - importlib-metadata >=4.13.0 + - fsspec >=2021.9.0 - packaging >=20.0 - partd >=1.4.0 - - python >=3.10 - pyyaml >=5.3.1 - toolz >=0.10.0 + - importlib-metadata >=4.13.0 + - python license: BSD-3-Clause - license_family: BSD purls: - pkg:pypi/dask?source=hash-mapping - size: 993940 - timestamp: 1747771723761 -- conda: https://conda.anaconda.org/conda-forge/noarch/datamodel-code-generator-0.33.0-pyhe01879c_0.conda - sha256: d8ce35029092da878a1d0ae25144cd73140057e32683345a77e6302998892430 - md5: c001a653f92de6f95bf42492f5197a15 + size: 1060758 + timestamp: 1762449427391 +- conda: https://conda.anaconda.org/conda-forge/noarch/datamodel-code-generator-0.35.0-pyhcf101f3_0.conda + sha256: 7c231e385a97c68c46d7d1859ae733c7811704ade352a6b94a228610a0c31d3d + md5: a51daf10dc4ea7cb46a8ead9e9773017 depends: - - python >=3.9 + - python >=3.10 - argcomplete >=2.10.1,<4 - black >=19.10b0 - genson >=1.2.1,<2 @@ -2752,8 +2799,8 @@ packages: license_family: MIT purls: - pkg:pypi/datamodel-code-generator?source=hash-mapping - size: 88592 - timestamp: 1755543932330 + size: 88888 + timestamp: 1762018245619 - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda sha256: 3b988146a50e165f0fa4e839545c679af88e4782ec284cc7b6d07dd226d6a068 md5: 679616eb5ad4e521c83da4650860aba7 @@ -2770,50 +2817,54 @@ packages: purls: [] size: 437860 timestamp: 1747855126005 -- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.14-py313h46c70d0_0.conda - sha256: bc2f3c177dcfe90f66df4c15803d6c44fd1f2e163683a70f816851c91a37631b - md5: 8c162409281c1e91b1e659c3a2115d28 +- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.17-py313h5d5ffb9_0.conda + sha256: 4c12ca7541d488f64ee92d6368e9a0a418e919c0b8c51517ff329b4259b4aaf8 + md5: be318961d544421f4c8d8a91bff4f118 depends: + - python + - libgcc >=14 + - libstdcxx >=14 + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: MIT license_family: MIT purls: - pkg:pypi/debugpy?source=hash-mapping - size: 2620835 - timestamp: 1744321405497 -- conda: https://conda.anaconda.org/conda-forge/osx-64/debugpy-1.8.14-py313h14b76d3_0.conda - sha256: 939eede351b9010f239289b4d703277f66b105a54d1222d6fe65f1da347bbecd - md5: a3418707dd82069f9c9758c297a2f363 + size: 2868018 + timestamp: 1758162048107 +- conda: https://conda.anaconda.org/conda-forge/osx-64/debugpy-1.8.17-py313hff8d55d_0.conda + sha256: 1a423f5335885e27a89f36663ec971a79435fdcb4842660d4c0568bcb55b016d + md5: 9e16c3b74fac3e83ed116fe8e3cf0da1 depends: + - python - __osx >=10.13 - - libcxx >=18 - - python >=3.13,<3.14.0a0 + - libcxx >=19 - python_abi 3.13.* *_cp313 license: MIT license_family: MIT purls: - pkg:pypi/debugpy?source=hash-mapping - size: 2578110 - timestamp: 1744321484203 -- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.14-py313h5813708_0.conda - sha256: dafd02b080118f11c7aea830d8e1c263134b90cf7e5518440fab46992130c100 - md5: d5d1eaa5f605092cc407ed0bfb5e16bf + size: 2768449 + timestamp: 1758162101542 +- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.17-py313h927ade5_0.conda + sha256: 83e33b2f0821ef043b502ed7261592eb18a7dcc43ec76213e2888d6fd99973e2 + md5: 9b792915c34565e7856fa9682879ccd2 depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 license: MIT license_family: MIT purls: - pkg:pypi/debugpy?source=hash-mapping - size: 3589078 - timestamp: 1744321801176 + size: 4000809 + timestamp: 1758162072333 - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda sha256: c17c6b9937c08ad63cb20a26f403a3234088e57d4455600974a0ce865cb14017 md5: 9ce473d1d1be1cc3810856a48b3fab32 @@ -2822,7 +2873,7 @@ packages: license: BSD-2-Clause license_family: BSD purls: - - pkg:pypi/decorator?source=compressed-mapping + - pkg:pypi/decorator?source=hash-mapping size: 14129 timestamp: 1740385067843 - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 @@ -2836,43 +2887,43 @@ packages: - pkg:pypi/defusedxml?source=hash-mapping size: 24062 timestamp: 1615232388757 -- conda: https://conda.anaconda.org/conda-forge/noarch/deprecated-1.2.18-pyhd8ed1ab_0.conda - sha256: d614bcff10696f1efc714df07651b50bf3808401fcc03814309ecec242cc8870 - md5: 0cef44b1754ae4d6924ac0eef6b9fdbe +- conda: https://conda.anaconda.org/conda-forge/noarch/deprecated-1.3.1-pyhd8ed1ab_0.conda + sha256: c994a70449d548dd388768090c71c1da81e1e128a281547ab9022908d46878c5 + md5: bf74a83f7a0f2a21b5d709997402cac4 depends: - - python >=3.9 + - python >=3.10 - wrapt <2,>=1.10 license: MIT license_family: MIT purls: - - pkg:pypi/deprecated?source=hash-mapping - size: 14382 - timestamp: 1737987072859 -- conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.9-pyhd8ed1ab_1.conda - sha256: 0e160c21776bd881b79ce70053e59736f51036784fa43a50da10a04f0c1b9c45 - md5: 8d88f4a2242e6b96f9ecff9a6a05b2f1 + - pkg:pypi/deprecated?source=compressed-mapping + size: 15815 + timestamp: 1761813872696 +- conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda + sha256: 6d977f0b2fc24fee21a9554389ab83070db341af6d6f09285360b2e09ef8b26e + md5: 003b8ba0a94e2f1e117d0bd46aebc901 depends: - python >=3.9 license: Apache-2.0 license_family: APACHE purls: - pkg:pypi/distlib?source=hash-mapping - size: 274151 - timestamp: 1733238487461 -- conda: https://conda.anaconda.org/conda-forge/noarch/distributed-2025.5.1-pyhd8ed1ab_0.conda - sha256: fc550701d648ba791f271068a792788047850bfd23ed082beb5317bb7d77a099 - md5: d2949f56a1479507e36e847681903376 + size: 275642 + timestamp: 1752823081585 +- conda: https://conda.anaconda.org/conda-forge/noarch/distributed-2025.11.0-pyhcf101f3_0.conda + sha256: 2c66187658069e66957b27265531e94911e9484276bb8a00a0377d25bc8d52ee + md5: a072de34cd7024a54f1b309bc9e36a3b depends: + - python >=3.10 - click >=8.0 - cloudpickle >=3.0.0 - cytoolz >=0.11.2 - - dask-core >=2025.5.1,<2025.5.2.0a0 + - dask-core >=2025.11.0,<2025.11.1.0a0 - jinja2 >=2.10.3 - locket >=1.0.0 - msgpack-python >=1.0.2 - packaging >=20.0 - psutil >=5.8.0 - - python >=3.10 - pyyaml >=5.4.1 - sortedcontainers >=2.0.5 - tblib >=1.6.0 @@ -2880,35 +2931,35 @@ packages: - tornado >=6.2.0 - urllib3 >=1.26.5 - zict >=3.0.0 + - python constrains: - openssl !=1.1.1e license: BSD-3-Clause - license_family: BSD purls: - pkg:pypi/distributed?source=hash-mapping - size: 799649 - timestamp: 1747775449784 -- conda: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.7.0-pyhff2d567_1.conda - sha256: 3ec40ccf63f2450c5e6c7dd579e42fc2e97caf0d8cd4ba24aa434e6fc264eda0 - md5: 5fbd60d61d21b4bd2f9d7a48fe100418 + size: 844827 + timestamp: 1762451399920 +- conda: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.8.0-pyhcf101f3_0.conda + sha256: ef1e7b8405997ed3d6e2b6722bd7088d4a8adf215e7c88335582e65651fb4e05 + md5: d73fdc05f10693b518f52c994d748c19 depends: - - python >=3.9,<4.0.0 + - python >=3.10,<4.0.0 - sniffio + - python constrains: - - aioquic >=1.0.0 - - wmi >=1.5.1 - - httpx >=0.26.0 - - trio >=0.23 - - cryptography >=43 + - aioquic >=1.2.0 + - cryptography >=45 - httpcore >=1.0.0 - - idna >=3.7 - - h2 >=4.1.0 + - httpx >=0.28.0 + - h2 >=4.2.0 + - idna >=3.10 + - trio >=0.30 + - wmi >=1.5.1 license: ISC - license_family: OTHER purls: - pkg:pypi/dnspython?source=hash-mapping - size: 172172 - timestamp: 1733256829961 + size: 196500 + timestamp: 1757292856922 - conda: https://conda.anaconda.org/conda-forge/noarch/donfig-0.8.1.post1-pyhd8ed1ab_1.conda sha256: d58e97d418f71703e822c422af5b9c431e3621a0ecdc8b0334c1ca33e076dfe7 md5: c56a7fa5597ad78b62e1f5d21f7f8b8f @@ -2939,27 +2990,27 @@ packages: requires_dist: - mypy>=1.15 ; extra == 'dev' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.2.0-pyhd8ed1ab_1.conda - sha256: b91a19eb78edfc2dbb36de9a67f74ee2416f1b5273dd7327abe53f2dbf864736 - md5: da16dd3b0b71339060cd44cb7110ddf9 +- conda: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.3.0-pyhd8ed1ab_0.conda + sha256: c37320864c35ef996b0e02e289df6ee89582d6c8e233e18dc9983375803c46bb + md5: 3bc0ac31178387e8ed34094d9481bfe8 depends: - dnspython >=2.0.0 - idna >=2.0.0 - - python >=3.9 + - python >=3.10 license: Unlicense purls: - pkg:pypi/email-validator?source=hash-mapping - size: 44401 - timestamp: 1733300827551 -- conda: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.2.0-hd8ed1ab_1.conda - sha256: e0d0fdf587aa0ed0ff08b2bce3ab355f46687b87b0775bfba01cc80a859ee6a2 - md5: 0794f8807ff2c6f020422cacb1bd7bfa + size: 46767 + timestamp: 1756221480106 +- conda: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.3.0-hd8ed1ab_0.conda + sha256: 6a518e00d040fcad016fb2dde29672aa3476cd9ae33ea5b7b257222e66037d89 + md5: 2452e434747a6b742adc5045f2182a8e depends: - - email-validator >=2.2.0,<2.2.1.0a0 + - email-validator >=2.3.0,<2.3.1.0a0 license: Unlicense purls: [] - size: 6552 - timestamp: 1733300828176 + size: 7077 + timestamp: 1756221480651 - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda sha256: ce61f4f99401a4bd455b89909153b40b9c823276aefcbb06f2044618696009ca md5: 72e42d28960d875c7654614f8b50939a @@ -2968,64 +3019,82 @@ packages: - typing_extensions >=4.6.0 license: MIT and PSF-2.0 purls: - - pkg:pypi/exceptiongroup?source=compressed-mapping + - pkg:pypi/exceptiongroup?source=hash-mapping size: 21284 timestamp: 1746947398083 -- conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.0-pyhd8ed1ab_0.conda - sha256: 7510dd93b9848c6257c43fdf9ad22adf62e7aa6da5f12a6a757aed83bcfedf05 - md5: 81d30c08f9a3e556e8ca9e124b044d14 +- conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + sha256: 210c8165a58fdbf16e626aac93cc4c14dbd551a01d1516be5ecad795d2422cad + md5: ff9efb7f7469aed3c4a8106ffa29593c depends: - - python >=3.9 + - python >=3.10 license: MIT license_family: MIT purls: - pkg:pypi/executing?source=hash-mapping - size: 29652 - timestamp: 1745502200340 -- conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.115.14-pyhe01879c_0.conda - sha256: 4e1d1aabe3199033c9c5a47176b0b4e0cd40621156fc72f706047c2348dd72ff - md5: 8f4fcc62c241e372495c19fe6f8b1908 + size: 30753 + timestamp: 1756729456476 +- conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.121.1-h4c1cb5d_0.conda + sha256: 0e9372741dead3facf15f4dea3f64fdb9554f64b9fe40224f4c7ae45d452d1ba + md5: 7cfbffd9a955daf74deb59475fe61897 + depends: + - fastapi-core ==0.121.1 pyhcf101f3_0 + - email_validator + - fastapi-cli + - httpx + - jinja2 + - python-multipart + - uvicorn-standard + license: MIT + purls: + - pkg:pypi/fastapi?source=compressed-mapping + size: 4787 + timestamp: 1762703623270 +- conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.16-pyhcf101f3_0.conda + sha256: 4e667b16965ae3e3cf81740a015bf5035c3bd3041b4d37add10108b2d7a633eb + md5: c550947a811dda38b00c69dabf974e5b depends: - - python >=3.9 - - starlette >=0.40.0,<0.47.0 + - python >=3.10 + - rich-toolkit >=0.14.8 + - typer >=0.15.1 + - uvicorn-standard >=0.15.0 + - python + license: MIT + purls: + - pkg:pypi/fastapi-cli?source=hash-mapping + size: 18987 + timestamp: 1762875919541 +- conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-core-0.121.1-pyhcf101f3_0.conda + sha256: e6b84dcbeb7a902c3259ae3a100e2d03a67c4fc30b2c4602210eb6dcd55e6ea6 + md5: 50976ce7dc9e1b0667028750fe1a7212 + depends: + - python >=3.10 + - annotated-doc >=0.0.2 + - starlette >=0.40.0,<0.50.0 - typing_extensions >=4.8.0 - pydantic >=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0 + - python + constrains: - email_validator >=2.0.0 - - fastapi-cli >=0.0.5 - - httpx >=0.23.0 + - fastapi-cli >=0.0.8 + - httpx >=0.23.0,<1.0.0 - jinja2 >=3.1.5 - python-multipart >=0.0.18 - uvicorn-standard >=0.12.0 - - python license: MIT purls: - pkg:pypi/fastapi?source=compressed-mapping - size: 78363 - timestamp: 1750986285010 -- conda: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.7-pyhd8ed1ab_0.conda - sha256: 300683731013b7221922339cd40430bb3c2ddeeb658fd7e37f5099ffe64e4db0 - md5: d960e0ea9e1c561aa928f6c4439f04c7 - depends: - - python >=3.9 - - rich-toolkit >=0.11.1 - - typer >=0.12.3 - - uvicorn-standard >=0.15.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/fastapi-cli?source=hash-mapping - size: 15546 - timestamp: 1734302408607 -- conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda - sha256: de7b6d4c4f865609ae88db6fa03c8b7544c2452a1aa5451eb7700aad16824570 - md5: 4547b39256e296bb758166893e909a7c + size: 86399 + timestamp: 1762703623265 +- conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda + sha256: 19025a4078ff3940d97eb0da29983d5e0deac9c3e09b0eabf897daeaf9d1114e + md5: 66b8b26023b8efdf8fcb23bac4b6325d depends: - - python >=3.9 + - python >=3.10 license: Unlicense purls: - pkg:pypi/filelock?source=hash-mapping - size: 17887 - timestamp: 1741969612334 + size: 17976 + timestamp: 1759948208140 - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda sha256: 2509992ec2fd38ab27c7cdb42cf6cadc566a1cc0d1021a2673475d9fa87c6276 md5: d3549fd50d450b6d9e7dddff25dd2110 @@ -3038,17 +3107,17 @@ packages: - pkg:pypi/fqdn?source=hash-mapping size: 16705 timestamp: 1733327494780 -- conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.5.1-pyhd8ed1ab_0.conda - sha256: cd6ae92ae5aa91a7e58cf39f1442d4821279f43f1c9499d15f45558d4793d1e0 - md5: 2d2c9ef879a7e64e2dc657b09272c2b6 +- conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda + sha256: df5cb57bb668cd5b2072d8bd66380ff7acb12e8c337f47dd4b9a75a6a6496a6d + md5: d18004c37182f83b9818b714825a7627 depends: - - python >=3.9 + - python >=3.10 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/fsspec?source=hash-mapping - size: 145521 - timestamp: 1748101667956 + size: 146592 + timestamp: 1761840236679 - pypi: ../eozilla/gavicore name: gavicore version: 0.0.8 @@ -3129,17 +3198,17 @@ packages: purls: [] size: 117017 timestamp: 1718284325443 -- conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.7.3-pyhd8ed1ab_0.conda - sha256: c1e4039c9b6d613e8e9feafa21fae58db5eebeaa5f8bece5d8610154ae6ebf80 - md5: aafe052f140a58b1afaf8ab473f5ac0d +- conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.15.0-pyhd8ed1ab_0.conda + sha256: 7a42213d6a6dae486c56a835a107fc8704eabf686a2b95adde009e06848426cd + md5: 0bc57a76679376b93a489824aa08c294 depends: - colorama >=0.4 - - python >=3.9 + - python >=3.10 license: ISC purls: - - pkg:pypi/griffe?source=compressed-mapping - size: 99814 - timestamp: 1745436578592 + - pkg:pypi/griffe?source=hash-mapping + size: 114576 + timestamp: 1762806629967 - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhd8ed1ab_0.conda sha256: f64b68148c478c3bfc8f8d519541de7d2616bf59d44485a5271041d40c061887 md5: 4b69232755285701bc86a5afe4d9933a @@ -3152,19 +3221,20 @@ packages: - pkg:pypi/h11?source=hash-mapping size: 37697 timestamp: 1745526482242 -- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda - sha256: 0aa1cdc67a9fe75ea95b5644b734a756200d6ec9d0dff66530aec3d1c1e9df75 - md5: b4754fb1bdcb70c8fd54f918301582c6 +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 + md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 depends: - - hpack >=4.1,<5 + - python >=3.10 - hyperframe >=6.1,<7 - - python >=3.9 + - hpack >=4.1,<5 + - python license: MIT license_family: MIT purls: - - pkg:pypi/h2?source=hash-mapping - size: 53888 - timestamp: 1738578623567 + - pkg:pypi/h2?source=compressed-mapping + size: 95967 + timestamp: 1756364871835 - conda: https://conda.anaconda.org/conda-forge/noarch/hatch-1.14.1-pyhd8ed1ab_0.conda sha256: d245185287bdf5d3c808267aebda2cb7fbce779099493f92e368f813e6a157d4 md5: 82f74ce5f4548c3627ed52dfac9da8ca @@ -3239,48 +3309,45 @@ packages: - pkg:pypi/httpcore?source=hash-mapping size: 49483 timestamp: 1745602916758 -- conda: https://conda.anaconda.org/conda-forge/linux-64/httptools-0.6.4-py313h536fd9c_0.conda - sha256: bb469a6efa00fad5ea8454ecb32a94f98a7f51b31540e4f14864beb363532aa8 - md5: 0a59582d8f8d588916b411e4b88db32e +- conda: https://conda.anaconda.org/conda-forge/linux-64/httptools-0.7.1-py313h07c4f96_1.conda + sha256: 0d549eca227e015b272c33646cdaed34d4619f6fe6d6196e2fddc31ec5144df9 + md5: 98e227930f49172e4f44ae8063341b0e depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: MIT - license_family: MIT purls: - pkg:pypi/httptools?source=hash-mapping - size: 99180 - timestamp: 1732707773985 -- conda: https://conda.anaconda.org/conda-forge/osx-64/httptools-0.6.4-py313h63b0ddb_0.conda - sha256: 056bd3423e91a0b54b27014918e1ba1918f96ea778b9b6797f1ae1ddd6c8f6a6 - md5: d35d66dc92e8878a5d53745dc048f2c8 + size: 98479 + timestamp: 1762504150954 +- conda: https://conda.anaconda.org/conda-forge/osx-64/httptools-0.7.1-py313hf050af9_1.conda + sha256: a6644bdc3220a3efb3b3b096dac59087b1ac5e134f4ad9f5cf5a1a958f364f0d + md5: da6a6e53e4c578394df6fcc946e41e47 depends: - __osx >=10.13 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: MIT - license_family: MIT purls: - pkg:pypi/httptools?source=hash-mapping - size: 83966 - timestamp: 1732707955739 -- conda: https://conda.anaconda.org/conda-forge/win-64/httptools-0.6.4-py313ha7868ed_0.conda - sha256: 3b8eeca5a9034a6f1f7537824410a87202c65e20252715390ef3a85d7b533ebb - md5: a81b2f33ac89c3df3ac2052ef60a611e + size: 89566 + timestamp: 1762504468066 +- conda: https://conda.anaconda.org/conda-forge/win-64/httptools-0.7.1-py313h5ea7bf4_1.conda + sha256: 2f49ccada1bfc65bfaa0c81c0e5043bb3daa0e0e9b249906c3958fb3fe05591c + md5: 0d3f5abff0435d2d2859ad73947f0ea9 depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT - license_family: MIT purls: - pkg:pypi/httptools?source=hash-mapping - size: 73806 - timestamp: 1732707911850 + size: 75294 + timestamp: 1762504395525 - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda sha256: cd0f1de3697b252df95f98383e9edb1d00386bfdd03fdf607fa42fe5fcb09950 md5: d6989ead454181f4f9bc987d3dc4e285 @@ -3332,27 +3399,17 @@ packages: purls: [] size: 12129203 timestamp: 1720853576813 -- conda: https://conda.anaconda.org/conda-forge/osx-64/icu-75.1-h120a0e1_0.conda - sha256: 2e64307532f482a0929412976c8450c719d558ba20c0962832132fd0d07ba7a7 - md5: d68d48a3060eb5abdc1cdc8e2a3a5966 - depends: - - __osx >=10.13 - license: MIT - license_family: MIT - purls: [] - size: 11761697 - timestamp: 1720853679409 -- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda - sha256: d7a472c9fd479e2e8dcb83fb8d433fce971ea369d704ece380e876f9c3494e87 - md5: 39a4f67be3286c86d696df570b1201b7 +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda + sha256: ae89d0299ada2a3162c2614a9d26557a92aa6a77120ce142f8e0109bbf0342b0 + md5: 53abe63df7e10a6ba605dc5f9f961d36 depends: - - python >=3.9 + - python >=3.10 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/idna?source=hash-mapping - size: 49765 - timestamp: 1733211921194 + size: 50721 + timestamp: 1760286526795 - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda sha256: c18ab120a0613ada4391b15981d86ff777b5690ca461ea7e9e49531e8f374745 md5: 63ccfdc3a3ce25b027b8767eb722fca8 @@ -3394,98 +3451,101 @@ packages: - pkg:pypi/inflect?source=hash-mapping size: 38377 timestamp: 1735424148811 -- conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda - sha256: 0ec8f4d02053cd03b0f3e63168316530949484f80e16f5e2fb199a1d117a89ca - md5: 6837f3eff7dcea42ecd714ce1ac2b108 +- conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda + sha256: e1a9e3b1c8fe62dc3932a616c284b5d8cbe3124bbfbedcf4ce5c828cb166ee19 + md5: 9614359868482abba1bd15ce465e3c42 depends: - - python >=3.9 + - python >=3.10 license: MIT license_family: MIT purls: - - pkg:pypi/iniconfig?source=hash-mapping - size: 11474 - timestamp: 1733223232820 -- conda: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.2.1-h57928b3_1083.conda - sha256: 0fd2b0b84c854029041b0ede8f4c2369242ee92acc0092f8407b1fe9238a8209 - md5: 2d89243bfb53652c182a7c73182cce4f - license: LicenseRef-IntelSimplifiedSoftwareOct2022 - license_family: Proprietary - purls: [] - size: 1852356 - timestamp: 1723739573141 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh3099207_0.conda - sha256: 33cfd339bb4efac56edf93474b37ddc049e08b1b4930cf036c893cc1f5a1f32a - md5: b40131ab6a36ac2c09b7c57d4d3fbf99 + - pkg:pypi/iniconfig?source=compressed-mapping + size: 13387 + timestamp: 1760831448842 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.31.0-pyh5552912_0.conda + sha256: 4eb35a7f81d43800c7d18b27c0fff9a2f23372839ac907ad116c24edcea6ab19 + md5: c83fa42af2cd5b2d4576d4501dad6232 depends: - - __linux + - appnope + - __osx - comm >=0.1.1 - debugpy >=1.6.5 - ipython >=7.23.1 - - jupyter_client >=6.1.12 + - jupyter_client >=8.0.0 - jupyter_core >=4.12,!=5.0.* - matplotlib-inline >=0.1 - - nest-asyncio - - packaging - - psutil - - python >=3.8 - - pyzmq >=24 - - tornado >=6.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 + - python >=3.10 + - pyzmq >=25 + - tornado >=6.2 - traitlets >=5.4.0 + - python + constrains: + - appnope >=0.1.2 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/ipykernel?source=hash-mapping - size: 119084 - timestamp: 1719845605084 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh4bbf305_0.conda - sha256: dc569094125127c0078aa536f78733f383dd7e09507277ef8bcd1789786e7086 - md5: 18df5fc4944a679e085e0e8f31775fc8 + size: 128210 + timestamp: 1760967038077 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.31.0-pyh6dadd2b_0.conda + sha256: 620bed30fed3942e52f63f0e7a9effdcaacf4aa2214145e052f3af143f211dec + md5: 192487fef6ebc9f726eaffb119a84286 depends: + - python - __win - comm >=0.1.1 - debugpy >=1.6.5 - ipython >=7.23.1 - - jupyter_client >=6.1.12 + - jupyter_client >=8.0.0 - jupyter_core >=4.12,!=5.0.* - matplotlib-inline >=0.1 - - nest-asyncio - - packaging - - psutil - - python >=3.8 - - pyzmq >=24 - - tornado >=6.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 + - python >=3.10 + - pyzmq >=25 + - tornado >=6.2 - traitlets >=5.4.0 + - python + constrains: + - appnope >=0.1.2 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/ipykernel?source=hash-mapping - size: 119853 - timestamp: 1719845858082 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh57ce528_0.conda - sha256: 072534d4d379225b2c3a4e38bc7730b65ae171ac7f0c2d401141043336e97980 - md5: 9eb15d654daa0ef5a98802f586bb4ffc + size: 128350 + timestamp: 1760967073264 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.31.0-pyha191276_0.conda + sha256: 35477c6ca12f48c3af0cbca01f65065dcc37c4a306886d6237e309e041b8434b + md5: d29c9fbbd0c41a7d4fbc5629314f3b00 depends: - - __osx - - appnope + - python + - __linux - comm >=0.1.1 - debugpy >=1.6.5 - ipython >=7.23.1 - - jupyter_client >=6.1.12 + - jupyter_client >=8.0.0 - jupyter_core >=4.12,!=5.0.* - matplotlib-inline >=0.1 - - nest-asyncio - - packaging - - psutil - - python >=3.8 - - pyzmq >=24 - - tornado >=6.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 + - python >=3.10 + - pyzmq >=25 + - tornado >=6.2 - traitlets >=5.4.0 + - python + constrains: + - appnope >=0.1.2 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/ipykernel?source=hash-mapping - size: 119568 - timestamp: 1719845667420 + size: 129645 + timestamp: 1760967030510 - conda: https://conda.anaconda.org/conda-forge/noarch/ipyleaflet-0.20.0-pyhd8ed1ab_0.conda sha256: 732befa245b4497631c3ba16fc817ed091c590f8737ffa9c10711879b61aa374 md5: 5005a985651bc467f48d17f733dd3c18 @@ -3504,22 +3564,20 @@ packages: - pkg:pypi/ipyleaflet?source=hash-mapping size: 34524 timestamp: 1749843287959 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.3.0-pyh6be1c34_0.conda - sha256: b6189de4e9f3d007a11e6e1df023c2bb73cf1864f63ca154c5ff8f0cdf601a50 - md5: 73e4ba4c8247f744be670f4da4f132e2 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.7.0-pyh53cf698_0.conda + sha256: b27fb08b14d82e896f35fe5ce889665aabb075bd540f9761c838d1d09a3d9704 + md5: 2d6b86a2e11b8cb2f20a432158ef10b9 depends: - - __win - - colorama - - decorator - - exceptiongroup - - ipython_pygments_lexers - - jedi >=0.16 - - matplotlib-inline - - pickleshare + - __unix + - pexpect >4.3 + - decorator >=4.3.2 + - ipython_pygments_lexers >=1.0.0 + - jedi >=0.18.1 + - matplotlib-inline >=0.1.5 - prompt-toolkit >=3.0.41,<3.1.0 - - pygments >=2.4.0 + - pygments >=2.11.0 - python >=3.11 - - stack_data + - stack_data >=0.6.0 - traitlets >=5.13.0 - typing_extensions >=4.6 - python @@ -3527,24 +3585,22 @@ packages: license_family: BSD purls: - pkg:pypi/ipython?source=hash-mapping - size: 621095 - timestamp: 1748711232331 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.3.0-pyhfa0c392_0.conda - sha256: ee5d526cba0c0a5981cbcbcadc37a76d257627a904ed2cd2db45821735c93ebd - md5: 270dbfb30fe759b39ce0c9fdbcd7be10 + size: 643036 + timestamp: 1762350942197 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.7.0-pyhe2676ad_0.conda + sha256: 3f48685fce2d2d75d24e9b18eba7d6d55f973d56cd4092064c98bb7f95a77dcc + md5: a1ac3cd378490356e0299d0ca95809d1 depends: - - __unix - - pexpect >4.3 - - decorator - - exceptiongroup - - ipython_pygments_lexers - - jedi >=0.16 - - matplotlib-inline - - pickleshare + - __win + - colorama >=0.4.4 + - decorator >=4.3.2 + - ipython_pygments_lexers >=1.0.0 + - jedi >=0.18.1 + - matplotlib-inline >=0.1.5 - prompt-toolkit >=3.0.41,<3.1.0 - - pygments >=2.4.0 + - pygments >=2.11.0 - python >=3.11 - - stack_data + - stack_data >=0.6.0 - traitlets >=5.13.0 - typing_extensions >=4.6 - python @@ -3552,8 +3608,8 @@ packages: license_family: BSD purls: - pkg:pypi/ipython?source=hash-mapping - size: 621859 - timestamp: 1748713870748 + size: 641867 + timestamp: 1762350976678 - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda sha256: 894682a42a7d659ae12878dbcb274516a7031bbea9104e92f8e88c1f2765a104 md5: bd80ba060603cc228d9d81c257093119 @@ -3566,22 +3622,22 @@ packages: - pkg:pypi/ipython-pygments-lexers?source=hash-mapping size: 13993 timestamp: 1737123723464 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.7-pyhd8ed1ab_0.conda - sha256: fd496e7d48403246f534c5eec09fc1e63ac7beb1fa06541d6ba71f56b30cf29b - md5: 7c9449eac5975ef2d7753da262a72707 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.8-pyhd8ed1ab_0.conda + sha256: 6bb58afb7eabc8b4ac0c7e92707fb498313cc0164cf04e7ba1090dbf49af514b + md5: d68e3f70d1f068f1b66d94822fdc644e depends: - comm >=0.1.3 - ipython >=6.1.0 - jupyterlab_widgets >=3.0.15,<3.1.0 - - python >=3.9 + - python >=3.10 - traitlets >=4.3.1 - widgetsnbextension >=4.0.14,<4.1.0 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/ipywidgets?source=compressed-mapping - size: 114557 - timestamp: 1746454722402 + - pkg:pypi/ipywidgets?source=hash-mapping + size: 114376 + timestamp: 1762040524661 - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets_bokeh-1.6.0-pyha770c72_2.conda sha256: 6a9db7e4bf7e19a2e6fe8b0f9e96ebdd2d7e5c8c0b84511190bf1dfb8fcf9e75 md5: d5a9f944e09636f00076fffd499cfb04 @@ -3609,17 +3665,18 @@ packages: - pkg:pypi/isoduration?source=hash-mapping size: 19832 timestamp: 1733493720346 -- conda: https://conda.anaconda.org/conda-forge/noarch/isort-6.0.1-pyhd8ed1ab_1.conda - sha256: e1d0e81e3c3da5d7854f9f57ffb89d8f4505bb64a2f05bb01d78eff24344a105 - md5: c25d1a27b791dab1797832aafd6a3e9a +- conda: https://conda.anaconda.org/conda-forge/noarch/isort-6.1.0-pyhd8ed1ab_0.conda + sha256: f93e415768129866c8f6b307bfb354fea17c17c1ecd287b32cb14ae9afc1c517 + md5: 1600dda6f61d2bc551676c2cebeb14e8 depends: - - python >=3.9,<4.0 + - importlib-metadata >=4.6.0 + - python >=3.10,<4.0 license: MIT license_family: MIT purls: - pkg:pypi/isort?source=hash-mapping - size: 75118 - timestamp: 1746190379093 + size: 75025 + timestamp: 1759362161158 - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.classes-3.4.0-pyhd8ed1ab_2.conda sha256: 3d16a0fa55a29fe723c918a979b2ee927eb0bf9616381cdfd26fa9ea2b649546 md5: ade6b25a6136661dadd1a43e4350b10b @@ -3644,9 +3701,9 @@ packages: - pkg:pypi/jaraco-context?source=hash-mapping size: 12483 timestamp: 1733382698758 -- conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.functools-4.1.0-pyhd8ed1ab_0.conda - sha256: 61da3e37149da5c8479c21571eaec61cc4a41678ee872dcb2ff399c30878dddb - md5: eb257d223050a5a27f5fdf5c9debc8ec +- conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.functools-4.3.0-pyhd8ed1ab_0.conda + sha256: 89320bb2c6bef18f5109bee6cb07a193701cf00552a4cfc6f75073cf0d3e44f6 + md5: b86839fa387a5b904846e77c84167e57 depends: - more-itertools - python >=3.9 @@ -3654,8 +3711,8 @@ packages: license_family: MIT purls: - pkg:pypi/jaraco-functools?source=hash-mapping - size: 15545 - timestamp: 1733746481844 + size: 16238 + timestamp: 1755584796828 - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda sha256: 92c4d217e2dc68983f724aa983cca5464dcb929c566627b26a2511159667dba8 md5: a4f4c5dc9b80bc50e0d3dc4e6e8f1bd9 @@ -3687,7 +3744,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jinja2?source=compressed-mapping + - pkg:pypi/jinja2?source=hash-mapping size: 112714 timestamp: 1741263433881 - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl @@ -3697,101 +3754,101 @@ packages: requires_dist: - six>=1.13.0 - editorconfig>=0.12.2 -- conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.12.0-pyhd8ed1ab_0.conda - sha256: 889e2a49de796475b5a4bc57d0ba7f4606b368ee2098e353a6d9a14b0e2c6393 - md5: 56275442557b3b45752c10980abfe2db +- conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.12.1-pyhd8ed1ab_0.conda + sha256: 4e08ccf9fa1103b617a4167a270768de736a36be795c6cd34c2761100d332f74 + md5: 0fc93f473c31a2f85c0bde213e7c63ca depends: - python >=3.9 license: Apache-2.0 license_family: APACHE purls: - pkg:pypi/json5?source=hash-mapping - size: 34114 - timestamp: 1743722170015 -- conda: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-3.0.0-py313h78bf25f_1.conda - sha256: 18d412dc91ee7560f0f94c19bb1c3c23f413b9a7f55948e2bb3ce44340439a58 - md5: 668d64b50e7ce7984cfe09ed7045b9fa + size: 34191 + timestamp: 1755034963991 +- conda: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-3.0.0-py313h78bf25f_2.conda + sha256: 9174f5209f835cc8918acddc279be919674d874179197e025181fe2a71cb0bce + md5: c1375f38e5f3ee38a9ee0e405a601c35 depends: - - python >=3.13.0rc1,<3.14.0a0 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/jsonpointer?source=hash-mapping - size: 17568 - timestamp: 1725303033801 -- conda: https://conda.anaconda.org/conda-forge/osx-64/jsonpointer-3.0.0-py313habf4b1d_1.conda - sha256: f4fdd6b6451492d0b179efcd31b0b3b75ec6d6ee962ea50e693f5e71a94089b7 - md5: a93dd2fcffa0290ca107f3bda7bc68ac + size: 18143 + timestamp: 1756754243113 +- conda: https://conda.anaconda.org/conda-forge/osx-64/jsonpointer-3.0.0-py313habf4b1d_2.conda + sha256: 444b99db8da2f87910967012bca4767dbc27024604cb11674baf5b33ad05e216 + md5: 6c9ecc26d54c3b9f9c40a7a21f780243 depends: - - python >=3.13.0rc1,<3.14.0a0 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/jsonpointer?source=hash-mapping - size: 17733 - timestamp: 1725303034373 -- conda: https://conda.anaconda.org/conda-forge/win-64/jsonpointer-3.0.0-py313hfa70ccb_1.conda - sha256: a0625cb0e86775b8996b4ee7117f1912b2fa3d76be8d10bf1d7b39578f5d99f7 - md5: 001efbf150f0ca5fd0a0c5e6e713c1d1 + size: 18208 + timestamp: 1756754393540 +- conda: https://conda.anaconda.org/conda-forge/win-64/jsonpointer-3.0.0-py313hfa70ccb_2.conda + sha256: dda25a66128a7b883515a659cd53c694e735374ccfbfa87a998160a33679424a + md5: 8da802c2a92986f7054f97c45e0f4bee depends: - - python >=3.13.0rc1,<3.14.0a0 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/jsonpointer?source=hash-mapping - size: 42805 - timestamp: 1725303293802 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.24.0-pyhd8ed1ab_0.conda - sha256: 812134fabb49493a50f7f443dc0ffafd0f63766f403a0bd8e71119763e57456a - md5: 59220749abcd119d645e6879983497a1 + size: 43276 + timestamp: 1756754377785 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.25.1-pyhe01879c_0.conda + sha256: ac377ef7762e49cb9c4f985f1281eeff471e9adc3402526eea78e6ac6589cf1d + md5: 341fd940c242cf33e832c0402face56f depends: - attrs >=22.2.0 - - importlib_resources >=1.4.0 - - jsonschema-specifications >=2023.03.6 - - pkgutil-resolve-name >=1.3.10 + - jsonschema-specifications >=2023.3.6 - python >=3.9 - referencing >=0.28.4 - rpds-py >=0.7.1 + - python license: MIT license_family: MIT purls: - pkg:pypi/jsonschema?source=hash-mapping - size: 75124 - timestamp: 1748294389597 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.4.1-pyh29332c3_0.conda - sha256: 66fbad7480f163509deec8bd028cd3ea68e58022982c838683586829f63f3efa - md5: 41ff526b1083fde51fbdc93f29282e0e + size: 81688 + timestamp: 1755595646123 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 + md5: 439cd0f567d697b20a8f45cb70a1005a depends: - - python >=3.9 + - python >=3.10 - referencing >=0.31.0 - python license: MIT license_family: MIT purls: - pkg:pypi/jsonschema-specifications?source=hash-mapping - size: 19168 - timestamp: 1745424244298 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.24.0-hd8ed1ab_0.conda - sha256: 970a1efffe29474d6bb3e4d63bc04105c5611d1c7e2cd7e2d43d1ba468f33c20 - md5: b4eaebf6fac318db166238796d2a9702 + size: 19236 + timestamp: 1757335715225 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.25.1-he01879c_0.conda + sha256: aef6705fe1335e6472e1b6365fcdb586356b18dceff72d8d6a315fc90e900ccf + md5: 13e31c573c884962318a738405ca3487 depends: + - jsonschema >=4.25.1,<4.25.2.0a0 - fqdn - idna - isoduration - jsonpointer >1.13 - - jsonschema >=4.24.0,<4.24.1.0a0 - rfc3339-validator - rfc3986-validator >0.1.0 + - rfc3987-syntax >=1.1.0 - uri-template - webcolors >=24.6.0 license: MIT license_family: MIT purls: [] - size: 7717 - timestamp: 1748294391013 + size: 4744 + timestamp: 1755595646123 - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-1.1.1-pyhd8ed1ab_1.conda sha256: b538e15067d05768d1c0532a6d9b0625922a1cce751dd6a2af04f7233a1a70e9 md5: 9453512288d20847de4356327d0e1282 @@ -3809,20 +3866,20 @@ packages: - pkg:pypi/jupyter?source=hash-mapping size: 8891 timestamp: 1733818677113 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.5-pyhe01879c_2.conda - sha256: f2ca86b121bcfeaf0241a927824459ba8712e64806b98dd262eb2b1a7c4e82a6 - md5: 7ed6505c703f3c4e1a58864bf84505e2 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.0-pyhcf101f3_0.conda + sha256: 897ad2e2c2335ef3c2826d7805e16002a1fd0d509b4ae0bc66617f0e0ff07bc2 + md5: 62b7c96c6cd77f8173cc5cada6a9acaa depends: - importlib-metadata >=4.8.3 - jupyter_server >=1.1.2 - - python >=3.9 + - python >=3.10 - python license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/jupyter-lsp?source=hash-mapping - size: 57659 - timestamp: 1748550130303 + size: 60377 + timestamp: 1756388269267 - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda sha256: 19d8bd5bb2fde910ec59e081eeb59529491995ce0d653a5209366611023a0b3a md5: 4ebae00eae9705b0c3d6d1018a81d047 @@ -3859,36 +3916,42 @@ packages: - pkg:pypi/jupyter-console?source=hash-mapping size: 26874 timestamp: 1733818130068 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.8.1-pyh31011fe_0.conda - sha256: 56a7a7e907f15cca8c4f9b0c99488276d4cb10821d2d15df9245662184872e81 - md5: b7d89d860ebcda28a5303526cdee68ab +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda + sha256: ed709a6c25b731e01563521ef338b93986cd14b5bc17f35e9382000864872ccc + md5: a8db462b01221e9f5135be466faeb3e0 depends: - - __unix + - __win + - pywin32 - platformdirs >=2.5 - - python >=3.8 + - python >=3.10 - traitlets >=5.3 + - python + constrains: + - pywin32 >=300 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyter-core?source=compressed-mapping - size: 59562 - timestamp: 1748333186063 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.8.1-pyh5737063_0.conda - sha256: 928c2514c2974fda78447903217f01ca89a77eefedd46bf6a2fe97072df57e8d - md5: 324e60a0d3f39f268e899709575ea3cd + - pkg:pypi/jupyter-core?source=hash-mapping + size: 64679 + timestamp: 1760643889625 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + sha256: 1d34b80e5bfcd5323f104dbf99a2aafc0e5d823019d626d0dce5d3d356a2a52a + md5: b38fe4e78ee75def7e599843ef4c1ab0 depends: - - __win - - cpython + - __unix + - python - platformdirs >=2.5 - - python >=3.8 - - pywin32 >=300 + - python >=3.10 - traitlets >=5.3 + - python + constrains: + - pywin32 >=300 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyter-core?source=compressed-mapping - size: 59972 - timestamp: 1748333368923 + - pkg:pypi/jupyter-core?source=hash-mapping + size: 65503 + timestamp: 1760643864586 - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyh29332c3_0.conda sha256: 37e6ac3ccf7afcc730c3b93cb91a13b9ae827fd306f35dd28f958a74a14878b5 md5: f56000b36f09ab7533877e695e4e8cb0 @@ -3906,7 +3969,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyter-events?source=compressed-mapping + - pkg:pypi/jupyter-events?source=hash-mapping size: 23647 timestamp: 1738765986736 - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_leaflet-0.20.0-pyhd8ed1ab_0.conda @@ -3920,9 +3983,9 @@ packages: - pkg:pypi/jupyter-leaflet?source=hash-mapping size: 615890 timestamp: 1749843262566 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.16.0-pyhe01879c_0.conda - sha256: 0082fb6f0afaf872affee4cde3b210f7f7497a5fb47f2944ab638fef0f0e2e77 - md5: f062e04d7cd585c937acbf194dceec36 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda + sha256: 74c4e642be97c538dae1895f7052599dfd740d8bd251f727bce6453ce8d6cd9a + md5: d79a87dcfa726bcea8e61275feed6f83 depends: - anyio >=3.1.0 - argon2-cffi >=21.1 @@ -3936,7 +3999,7 @@ packages: - overrides >=5.0 - packaging >=22.0 - prometheus_client >=0.9 - - python >=3.9 + - python >=3.10 - pyzmq >=24 - send2trash >=1.8.2 - terminado >=0.8.3 @@ -3948,8 +4011,8 @@ packages: license_family: BSD purls: - pkg:pypi/jupyter-server?source=hash-mapping - size: 344376 - timestamp: 1747083217715 + size: 347094 + timestamp: 1755870522134 - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_1.conda sha256: 0890fc79422191bc29edf17d7b42cff44ba254aa225d31eb30819f8772b775b8 md5: 2d983ff1b82a1ccb6f2e9d8784bdd6bd @@ -3962,14 +4025,14 @@ packages: - pkg:pypi/jupyter-server-terminals?source=hash-mapping size: 19711 timestamp: 1733428049134 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.4.3-pyhd8ed1ab_0.conda - sha256: fc0235a71d852734fe92183a78cb91827367573450eba82465ae522c64230736 - md5: 4861a0c2a5a5d0481a450a9dfaf9febe +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.4.10-pyhd8ed1ab_0.conda + sha256: 1ce33112e545bcfc41f92747f4f8b0f36310937339334bfaabe2496a65b3f5b2 + md5: 0fc7cfcd261709ef5591c1ea3415e8a7 depends: - async-lru >=1.0.0 - - httpx >=0.25.0 + - httpx >=0.25.0,<1 - importlib-metadata >=4.8.3 - - ipykernel >=6.5.0 + - ipykernel >=6.5.0,!=6.30.0 - jinja2 >=3.0.3 - jupyter-lsp >=2.0.0 - jupyter_core @@ -3977,7 +4040,7 @@ packages: - jupyterlab_server >=2.27.1,<3 - notebook-shim >=0.2 - packaging - - python >=3.9 + - python >=3.10 - setuptools >=41.1.0 - tomli >=1.2.2 - tornado >=6.2.0 @@ -3985,9 +4048,9 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyterlab?source=hash-mapping - size: 8236973 - timestamp: 1748273017680 + - pkg:pypi/jupyterlab?source=compressed-mapping + size: 8034306 + timestamp: 1761146412485 - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda sha256: dc24b900742fdaf1e077d9a3458fd865711de80bca95fe3c6d46610c532c6ef0 md5: fd312693df06da3578383232528c468d @@ -4002,43 +4065,42 @@ packages: - pkg:pypi/jupyterlab-pygments?source=hash-mapping size: 18711 timestamp: 1733328194037 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.3-pyhd8ed1ab_1.conda - sha256: d03d0b7e23fa56d322993bc9786b3a43b88ccc26e58b77c756619a921ab30e86 - md5: 9dc4b2b0f41f0de41d27f3293e319357 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + sha256: 381d2d6a259a3be5f38a69463e0f6c5dcf1844ae113058007b51c3bef13a7cee + md5: a63877cb23de826b1620d3adfccc4014 depends: - babel >=2.10 - - importlib-metadata >=4.8.3 - jinja2 >=3.0.3 - json5 >=0.9.0 - jsonschema >=4.18 - jupyter_server >=1.21,<3 - packaging >=21.3 - - python >=3.9 + - python >=3.10 - requests >=2.31 - constrains: - - openapi-core >=0.18.0,<0.19.0 + - python license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/jupyterlab-server?source=hash-mapping - size: 49449 - timestamp: 1733599666357 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.15-pyhd8ed1ab_0.conda - sha256: 6214d345861b106076e7cb38b59761b24cd340c09e3f787e4e4992036ca3cd7e - md5: ad100d215fad890ab0ee10418f36876f + size: 51621 + timestamp: 1761145478692 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.16-pyhcf101f3_1.conda + sha256: 5c03de243d7ae6247f39a402f4785d95e61c3be79ef18738e8f17155585d31a8 + md5: dbf8b81974504fa51d34e436ca7ef389 depends: - - python >=3.9 + - python >=3.10 + - python constrains: - jupyterlab >=3,<5 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyterlab-widgets?source=hash-mapping - size: 189133 - timestamp: 1746450926999 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupytext-1.17.3-pyh80e38bb_0.conda - sha256: 2da4cfec3f811a37caa583e572ad2dad0b1d5c34f5d7121b4c687692bf1a4a06 - md5: 3178d138046fbc2e4944d3642a326814 + - pkg:pypi/jupyterlab-widgets?source=compressed-mapping + size: 216779 + timestamp: 1762267481404 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupytext-1.18.1-pyh80e38bb_0.conda + sha256: 07063dad3019455d786dc3b5174731eb0ef53eb699df25e21571c2b7cdcf0fd0 + md5: 3c85f79f1debe2d2c82ac08f1c1126e1 depends: - markdown-it-py >=1.0 - mdit-py-plugins @@ -4051,8 +4113,8 @@ packages: license_family: MIT purls: - pkg:pypi/jupytext?source=hash-mapping - size: 109845 - timestamp: 1756451506971 + size: 111205 + timestamp: 1760888130421 - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.6.0-pyh534df25_0.conda sha256: c8b436fa9853bf8b836c96afbb7684a04955b80b37f5d5285fd836b6a8566cc5 md5: d2c0c5bda93c249f877c7fceea9e63af @@ -4107,15 +4169,16 @@ packages: - pkg:pypi/keyring?source=hash-mapping size: 36985 timestamp: 1735210286595 -- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 - sha256: 150c05a6e538610ca7c43beb3a40d65c90537497a4f6a5f4d15ec0451b6f5ebb - md5: 30186d27e2c9fa62b45fb1476b7200e3 +- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 + md5: b38117a3c920364aff79f870c984b4a3 depends: - - libgcc-ng >=10.3.0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 license: LGPL-2.1-or-later purls: [] - size: 117831 - timestamp: 1646151697040 + size: 134088 + timestamp: 1754905959823 - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda sha256: 99df692f7a8a5c27cd14b5fb1374ee55e756631b9c3d659ed3ee60830249b238 md5: 3f43953b7d3fb3aaa1d0d0723d91e368 @@ -4158,6 +4221,17 @@ packages: purls: [] size: 712034 timestamp: 1719463874284 +- conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + sha256: 49570840fb15f5df5d4b4464db8ee43a6d643031a2bc70ef52120a52e3809699 + md5: 9b965c999135d43a3d0f7bd7d024e26a + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/lark?source=compressed-mapping + size: 94312 + timestamp: 1761596921009 - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda sha256: d6a61830a354da022eae93fa896d0991385a875c6bba53c82263a289deda9db8 md5: 000e85703f0fd9594c81710dd5066471 @@ -4197,18 +4271,18 @@ packages: purls: [] size: 510641 timestamp: 1739161381270 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h1423503_5.conda - sha256: dcd2b1a065bbf5c54004ddf6551c775a8eb6993c8298ca8a6b92041ed413f785 - md5: 6dc9e1305e7d3129af4ad0dabda30e56 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1aa0949_5.conda + sha256: dab1fbf65abb05d3f2ee49dff90d60eeb2e02039fcb561343c7cea5dea523585 + md5: 511ed8935448c1875776b60ad3daf3a1 depends: - __glibc >=2.17,<3.0.a0 + - zstd >=1.5.7,<1.6.0a0 constrains: - - binutils_impl_linux-64 2.43 + - binutils_impl_linux-64 2.44 license: GPL-3.0-only - license_family: GPL purls: [] - size: 670635 - timestamp: 1749858327854 + size: 741516 + timestamp: 1762674665675 - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda sha256: 412381a43d5ff9bbed82cd52a0bbca5b90623f62e41007c9c42d3870c60945ff md5: 9344155d33912347b37f0ae6c410a835 @@ -4244,514 +4318,573 @@ packages: purls: [] size: 164701 timestamp: 1745264384716 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20250127.1-cxx17_hbbce691_0.conda - sha256: 65d5ca837c3ee67b9d769125c21dc857194d7f6181bb0e7bd98ae58597b457d0 - md5: 00290e549c5c8a32cc271020acc9ec6b +- conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20250512.1-cxx17_hba17884_0.conda + sha256: dcd1429a1782864c452057a6c5bc1860f2b637dc20a2b7e6eacd57395bbceff8 + md5: 83b160d4da3e1e847bf044997621ed63 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=13 - libstdcxx >=13 constrains: - - abseil-cpp =20250127.1 - - libabseil-static =20250127.1=cxx17* + - libabseil-static =20250512.1=cxx17* + - abseil-cpp =20250512.1 license: Apache-2.0 license_family: Apache purls: [] - size: 1325007 - timestamp: 1742369558286 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libabseil-20250127.1-cxx17_h0e468a2_0.conda - sha256: 8c43a7daa4df04f66d08e6a6cd2f004fc84500bf8c0c75dc9ee633b34c2a01be - md5: b2004ae68003d2ef310b49847b911e4b + size: 1310612 + timestamp: 1750194198254 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libabseil-20250512.1-cxx17_hfc00f1c_0.conda + sha256: a878efebf62f039a1f1733c1e150a75a99c7029ece24e34efdf23d56256585b1 + md5: ddf1acaed2276c7eb9d3c76b49699a11 depends: - __osx >=10.13 - libcxx >=18 constrains: - - libabseil-static =20250127.1=cxx17* - - abseil-cpp =20250127.1 + - abseil-cpp =20250512.1 + - libabseil-static =20250512.1=cxx17* license: Apache-2.0 license_family: Apache purls: [] - size: 1177855 - timestamp: 1742369859708 -- conda: https://conda.anaconda.org/conda-forge/win-64/libabseil-20250127.1-cxx17_h4eb7d71_0.conda - sha256: 61ece8d3768604eae2c7c869a5c032a61fbfb8eb86cc85dc39cc2de48d3827b4 - md5: 9619870922c18fa283a3ee703a14cfcc + size: 1162435 + timestamp: 1750194293086 +- conda: https://conda.anaconda.org/conda-forge/win-64/libabseil-20250512.1-cxx17_habfad5f_0.conda + sha256: 78790771f44e146396d9ae92efbe1022168295afd8d174f653a1fa16f0f0fa32 + md5: d6a4cd236fc1c69a1cfc9698fb5e391f depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.42.34438 constrains: - - libabseil-static =20250127.1=cxx17* - - abseil-cpp =20250127.1 + - libabseil-static =20250512.1=cxx17* + - abseil-cpp =20250512.1 license: Apache-2.0 license_family: Apache purls: [] - size: 1836732 - timestamp: 1742370096247 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-20.0.0-h314c690_7_cpu.conda - build_number: 7 - sha256: fcdec351aac8d5114171e01ec7bc21e8924c665fe52b7ce82612148b0a1c81e4 - md5: e31c941000c86b5a52b5d520cdff7e20 + size: 1615210 + timestamp: 1750194549591 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-22.0.0-h99e40f8_3_cpu.conda + build_number: 3 + sha256: 965421021737fdb2cef2f85f247c8840309c46cf73253655a0e9054011d1238b + md5: 9d1326422f5f06fec734834a617042eb depends: - __glibc >=2.17,<3.0.a0 - - aws-crt-cpp >=0.32.8,<0.32.9.0a0 - - aws-sdk-cpp >=1.11.510,<1.11.511.0a0 - - azure-core-cpp >=1.14.0,<1.14.1.0a0 - - azure-identity-cpp >=1.10.0,<1.10.1.0a0 - - azure-storage-blobs-cpp >=12.13.0,<12.13.1.0a0 - - azure-storage-files-datalake-cpp >=12.12.0,<12.12.1.0a0 + - aws-crt-cpp >=0.35.0,<0.35.1.0a0 + - aws-sdk-cpp >=1.11.606,<1.11.607.0a0 + - azure-core-cpp >=1.16.1,<1.16.2.0a0 + - azure-identity-cpp >=1.13.2,<1.13.3.0a0 + - azure-storage-blobs-cpp >=12.15.0,<12.15.1.0a0 + - azure-storage-files-datalake-cpp >=12.13.0,<12.13.1.0a0 - bzip2 >=1.0.8,<2.0a0 - glog >=0.7.1,<0.8.0a0 - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libbrotlidec >=1.1.0,<1.2.0a0 - - libbrotlienc >=1.1.0,<1.2.0a0 - - libgcc >=13 - - libgoogle-cloud >=2.36.0,<2.37.0a0 - - libgoogle-cloud-storage >=2.36.0,<2.37.0a0 + - libabseil >=20250512.1,<20250513.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libgcc >=14 + - libgoogle-cloud >=2.39.0,<2.40.0a0 + - libgoogle-cloud-storage >=2.39.0,<2.40.0a0 - libopentelemetry-cpp >=1.21.0,<1.22.0a0 - - libprotobuf >=5.29.3,<5.29.4.0a0 - - libre2-11 >=2024.7.2 - - libstdcxx >=13 - - libutf8proc >=2.10.0,<2.11.0a0 + - libprotobuf >=6.31.1,<6.31.2.0a0 + - libstdcxx >=14 - libzlib >=1.3.1,<2.0a0 - lz4-c >=1.10.0,<1.11.0a0 - - orc >=2.1.2,<2.1.3.0a0 - - re2 - - snappy >=1.2.1,<1.3.0a0 + - orc >=2.2.1,<2.2.2.0a0 + - snappy >=1.2.2,<1.3.0a0 - zstd >=1.5.7,<1.6.0a0 constrains: - parquet-cpp <0.0a0 - - apache-arrow-proc =*=cpu - arrow-cpp <0.0a0 + - apache-arrow-proc =*=cpu license: Apache-2.0 license_family: APACHE purls: [] - size: 9194829 - timestamp: 1749948580961 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-20.0.0-hd0d6b81_7_cpu.conda - build_number: 7 - sha256: 08389ced263ffca3a90bb58ba91e4559a0d5f0fa12a7ec87221709a34762daea - md5: 3f622c0caf1a6d97d99de4d61286d58e - depends: - - __osx >=10.14 - - aws-crt-cpp >=0.32.8,<0.32.9.0a0 - - aws-sdk-cpp >=1.11.510,<1.11.511.0a0 - - azure-core-cpp >=1.14.0,<1.14.1.0a0 - - azure-identity-cpp >=1.10.0,<1.10.1.0a0 - - azure-storage-blobs-cpp >=12.13.0,<12.13.1.0a0 - - azure-storage-files-datalake-cpp >=12.12.0,<12.12.1.0a0 + size: 6293141 + timestamp: 1761789479175 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-22.0.0-hb95b15f_3_cpu.conda + build_number: 3 + sha256: a66cb3930c3fc34250f536baa6c9b785a2da82a2f99e073546dc1eabee996910 + md5: c20755935461d5e57f4d92f11ac287c6 + depends: + - __osx >=11.0 + - aws-crt-cpp >=0.35.0,<0.35.1.0a0 + - aws-sdk-cpp >=1.11.606,<1.11.607.0a0 + - azure-core-cpp >=1.16.1,<1.16.2.0a0 + - azure-identity-cpp >=1.13.2,<1.13.3.0a0 + - azure-storage-blobs-cpp >=12.15.0,<12.15.1.0a0 + - azure-storage-files-datalake-cpp >=12.13.0,<12.13.1.0a0 - bzip2 >=1.0.8,<2.0a0 - glog >=0.7.1,<0.8.0a0 - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libbrotlidec >=1.1.0,<1.2.0a0 - - libbrotlienc >=1.1.0,<1.2.0a0 - - libcxx >=18 - - libgoogle-cloud >=2.36.0,<2.37.0a0 - - libgoogle-cloud-storage >=2.36.0,<2.37.0a0 + - libabseil >=20250512.1,<20250513.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libcxx >=19 + - libgoogle-cloud >=2.39.0,<2.40.0a0 + - libgoogle-cloud-storage >=2.39.0,<2.40.0a0 - libopentelemetry-cpp >=1.21.0,<1.22.0a0 - - libprotobuf >=5.29.3,<5.29.4.0a0 - - libre2-11 >=2024.7.2 - - libutf8proc >=2.10.0,<2.11.0a0 + - libprotobuf >=6.31.1,<6.31.2.0a0 - libzlib >=1.3.1,<2.0a0 - lz4-c >=1.10.0,<1.11.0a0 - - orc >=2.1.2,<2.1.3.0a0 - - re2 - - snappy >=1.2.1,<1.3.0a0 + - orc >=2.2.1,<2.2.2.0a0 + - snappy >=1.2.2,<1.3.0a0 - zstd >=1.5.7,<1.6.0a0 constrains: - - parquet-cpp <0.0a0 - arrow-cpp <0.0a0 + - parquet-cpp <0.0a0 - apache-arrow-proc =*=cpu license: Apache-2.0 license_family: APACHE purls: [] - size: 6400048 - timestamp: 1749947096729 -- conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-20.0.0-hc090743_7_cpu.conda - build_number: 7 - sha256: 4316fb108220ff92c2d136739eded2af274e408217ead743618adb61994c602f - md5: cf6d28474325986a74f3e91f14e52928 + size: 4271857 + timestamp: 1761789712758 +- conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-22.0.0-h0832232_3_cpu.conda + build_number: 3 + sha256: 2ea68bc3a6a0d91b2263fc36df64d74a93d5fd9618038d26c90e64abd53064c2 + md5: 1b1f7301cd1ca39c70b581ae57f62bf5 depends: - - aws-crt-cpp >=0.32.8,<0.32.9.0a0 - - aws-sdk-cpp >=1.11.510,<1.11.511.0a0 + - aws-crt-cpp >=0.35.0,<0.35.1.0a0 + - aws-sdk-cpp >=1.11.606,<1.11.607.0a0 - bzip2 >=1.0.8,<2.0a0 - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libbrotlidec >=1.1.0,<1.2.0a0 - - libbrotlienc >=1.1.0,<1.2.0a0 + - libabseil >=20250512.1,<20250513.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 - libcrc32c >=1.1.2,<1.2.0a0 - - libcurl >=8.14.1,<9.0a0 - - libgoogle-cloud >=2.36.0,<2.37.0a0 - - libgoogle-cloud-storage >=2.36.0,<2.37.0a0 - - libprotobuf >=5.29.3,<5.29.4.0a0 - - libre2-11 >=2024.7.2 - - libutf8proc >=2.10.0,<2.11.0a0 + - libcurl >=8.16.0,<9.0a0 + - libgoogle-cloud >=2.39.0,<2.40.0a0 + - libgoogle-cloud-storage >=2.39.0,<2.40.0a0 + - libprotobuf >=6.31.1,<6.31.2.0a0 - libzlib >=1.3.1,<2.0a0 - lz4-c >=1.10.0,<1.11.0a0 - - orc >=2.1.2,<2.1.3.0a0 - - re2 - - snappy >=1.2.1,<1.3.0a0 + - orc >=2.2.1,<2.2.2.0a0 + - snappy >=1.2.2,<1.3.0a0 - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 - zstd >=1.5.7,<1.6.0a0 constrains: + - apache-arrow-proc =*=cpu - arrow-cpp <0.0a0 - parquet-cpp <0.0a0 - - apache-arrow-proc =*=cpu license: Apache-2.0 license_family: APACHE purls: [] - size: 5443166 - timestamp: 1749950428444 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-20.0.0-hcb10f89_7_cpu.conda - build_number: 7 - sha256: 37e19d7db9c8b6031e6a5036b7519c9d613acd6024f8bf36c51ed66a6702041a - md5: 241bdde1a0401bc6db4019d5908fa673 + size: 3993601 + timestamp: 1762051395845 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-22.0.0-h635bf11_3_cpu.conda + build_number: 3 + sha256: 23f6993e8ade76c1119e5fcf30e10f64a600462e6287ad8ce03039761eddf0ab + md5: 570b643cbd688d83dfd33bb8bb3faa6c depends: - __glibc >=2.17,<3.0.a0 - - libarrow 20.0.0 h314c690_7_cpu - - libgcc >=13 - - libstdcxx >=13 + - libarrow 22.0.0 h99e40f8_3_cpu + - libarrow-compute 22.0.0 h8c2c5c3_3_cpu + - libgcc >=14 + - libstdcxx >=14 license: Apache-2.0 license_family: APACHE purls: [] - size: 642249 - timestamp: 1749948657167 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-acero-20.0.0-hdc53af8_7_cpu.conda - build_number: 7 - sha256: 6eccfc297dacc52388dbd0b4c62baec479d4b320e66527c1a52ca3242d6bf1a1 - md5: 6a79428252200bf063fa9a40b1168ea1 + size: 580479 + timestamp: 1761789753482 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-acero-22.0.0-h2db2d7d_3_cpu.conda + build_number: 3 + sha256: ed59fdf0ae9e6b42ab05104128db34f786716049bbb40c8665d8c4bc45f400d5 + md5: 9c430e6b2ad599ba8c633f87af0cc5c4 depends: - - __osx >=10.14 - - libarrow 20.0.0 hd0d6b81_7_cpu - - libcxx >=18 + - __osx >=11.0 + - libabseil * cxx17* + - libabseil >=20250512.1,<20250513.0a0 + - libarrow 22.0.0 hb95b15f_3_cpu + - libarrow-compute 22.0.0 h7751554_3_cpu + - libcxx >=19 + - libopentelemetry-cpp >=1.21.0,<1.22.0a0 + - libprotobuf >=6.31.1,<6.31.2.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 549003 - timestamp: 1749947244329 -- conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-20.0.0-h7d8d6a5_7_cpu.conda - build_number: 7 - sha256: 12a50a06848cb04885b0154cb660acd21c16b40c8865d4deafd41d54e7b4b638 - md5: 061526bfa3efb4491fe81196519cdb37 + size: 552494 + timestamp: 1761790470821 +- conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-22.0.0-h7d8d6a5_3_cpu.conda + build_number: 3 + sha256: aab50fabd2fffcbf5b876ba57ff43c1ee36cd796dd8a57cd02ba1f0a1c7e0264 + md5: 65c96163acfbd0e87ab44d90e1796663 depends: - - libarrow 20.0.0 hc090743_7_cpu + - libarrow 22.0.0 h0832232_3_cpu + - libarrow-compute 22.0.0 h2db994a_3_cpu - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: APACHE purls: [] - size: 461614 - timestamp: 1749950548322 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-20.0.0-hcb10f89_7_cpu.conda - build_number: 7 - sha256: 3ca668ae0257d65b212a7c11516d22b062438e49b1ad72a98d96e5211cd63451 - md5: ab55d9094b97f25746f26cb988abe15b + size: 445027 + timestamp: 1762051703925 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-22.0.0-h8c2c5c3_3_cpu.conda + build_number: 3 + sha256: 9468058a3fc79a66df7acbe8b2a30637d3c8fab7fea615c1ae1661e4ba0d46f3 + md5: 11f3aeba99decd766f41affb5eef94c8 depends: - __glibc >=2.17,<3.0.a0 - - libarrow 20.0.0 h314c690_7_cpu - - libarrow-acero 20.0.0 hcb10f89_7_cpu - - libgcc >=13 - - libparquet 20.0.0 h081d1f1_7_cpu - - libstdcxx >=13 + - libarrow 22.0.0 h99e40f8_3_cpu + - libgcc >=14 + - libre2-11 >=2025.8.12 + - libstdcxx >=14 + - libutf8proc >=2.11.0,<2.12.0a0 + - re2 license: Apache-2.0 license_family: APACHE purls: [] - size: 607973 - timestamp: 1749948789812 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-dataset-20.0.0-hdc53af8_7_cpu.conda - build_number: 7 - sha256: 7eebfc1289f2bd276f4bc691812ef8adefeeb989232a92711f33368163044829 - md5: 8bb4416496c566ffa6de78d3107020d3 + size: 2970054 + timestamp: 1761789573653 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-compute-22.0.0-h7751554_3_cpu.conda + build_number: 3 + sha256: 113411d42557992e19e1f1e7db992af1ee50cd07391002eea0bc29c597a13353 + md5: 8f5328b8ace9e8821e7c05c6e450ee55 depends: - - __osx >=10.14 - - libarrow 20.0.0 hd0d6b81_7_cpu - - libarrow-acero 20.0.0 hdc53af8_7_cpu - - libcxx >=18 - - libparquet 20.0.0 h283e888_7_cpu + - __osx >=11.0 + - libabseil * cxx17* + - libabseil >=20250512.1,<20250513.0a0 + - libarrow 22.0.0 hb95b15f_3_cpu + - libcxx >=19 + - libopentelemetry-cpp >=1.21.0,<1.22.0a0 + - libprotobuf >=6.31.1,<6.31.2.0a0 + - libre2-11 >=2025.8.12 + - libutf8proc >=2.11.0,<2.12.0a0 + - re2 license: Apache-2.0 license_family: APACHE purls: [] - size: 530862 - timestamp: 1749947528774 -- conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-20.0.0-h7d8d6a5_7_cpu.conda - build_number: 7 - sha256: 586bbf1d1a8e5303514c42b61540e6575dcda58dbfbe103f71986faf01bc85fa - md5: d3f4d8c3b23d36e60c42e890a8d098b9 + size: 2394455 + timestamp: 1761789948257 +- conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-compute-22.0.0-h2db994a_3_cpu.conda + build_number: 3 + sha256: 3ee5e03eb7a4b1d693fccf702b4687a0fb1119f61c163f73e40d8bdb7f7cb99f + md5: 52d15143fc7987c8c587d41976f8fa24 depends: - - libarrow 20.0.0 hc090743_7_cpu - - libarrow-acero 20.0.0 h7d8d6a5_7_cpu - - libparquet 20.0.0 ha850022_7_cpu + - libarrow 22.0.0 h0832232_3_cpu + - libre2-11 >=2025.8.12 + - libutf8proc >=2.11.0,<2.12.0a0 + - re2 - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: APACHE purls: [] - size: 441197 - timestamp: 1749950768599 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-20.0.0-h1bed206_7_cpu.conda - build_number: 7 - sha256: c1e146098beb32de7060db899c4af2b57abe30cbaf9a2adf3e5e0f88511689db - md5: 9e6fb2001a6e86113231ebae5dd51dc9 + size: 1680745 + timestamp: 1762051518016 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-22.0.0-h635bf11_3_cpu.conda + build_number: 3 + sha256: acf68225881856b08f1cc4d5b31eaedf3f64e488ec197ea2474a92621e74e0a8 + md5: 3cdf76f800439a09aa99e62fd0af560f depends: - __glibc >=2.17,<3.0.a0 - - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libarrow 20.0.0 h314c690_7_cpu - - libarrow-acero 20.0.0 hcb10f89_7_cpu - - libarrow-dataset 20.0.0 hcb10f89_7_cpu - - libgcc >=13 - - libprotobuf >=5.29.3,<5.29.4.0a0 - - libstdcxx >=13 + - libarrow 22.0.0 h99e40f8_3_cpu + - libarrow-acero 22.0.0 h635bf11_3_cpu + - libarrow-compute 22.0.0 h8c2c5c3_3_cpu + - libgcc >=14 + - libparquet 22.0.0 h7376487_3_cpu + - libstdcxx >=14 license: Apache-2.0 license_family: APACHE purls: [] - size: 525519 - timestamp: 1749948876372 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-substrait-20.0.0-ha37b807_7_cpu.conda - build_number: 7 - sha256: b577c9c1a1329daed597479c85b1568673d881d65f47e6c0f29ae25c9bf312a0 - md5: 268748731672cecdfff15330c0a30f7d + size: 577896 + timestamp: 1761789864298 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-dataset-22.0.0-h2db2d7d_3_cpu.conda + build_number: 3 + sha256: f83de31850a9c1646a2f865bbd120a0f795263772ac8b8a9230186cde0dedce6 + md5: 70e46c4eff187a41d268633d63a299f3 depends: - - __osx >=10.14 + - __osx >=11.0 - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libarrow 20.0.0 hd0d6b81_7_cpu - - libarrow-acero 20.0.0 hdc53af8_7_cpu - - libarrow-dataset 20.0.0 hdc53af8_7_cpu - - libcxx >=18 - - libprotobuf >=5.29.3,<5.29.4.0a0 + - libabseil >=20250512.1,<20250513.0a0 + - libarrow 22.0.0 hb95b15f_3_cpu + - libarrow-acero 22.0.0 h2db2d7d_3_cpu + - libarrow-compute 22.0.0 h7751554_3_cpu + - libcxx >=19 + - libopentelemetry-cpp >=1.21.0,<1.22.0a0 + - libparquet 22.0.0 habb56ca_3_cpu + - libprotobuf >=6.31.1,<6.31.2.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 464998 - timestamp: 1749947724652 -- conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-substrait-20.0.0-hb76e781_7_cpu.conda - build_number: 7 - sha256: 8dbea8b9d02bcc6869eb750164baf7e991fa1679ba6f14ec906b82e883abdc73 - md5: b7787019cd124952d453b34efc5a0c4c - depends: + size: 533064 + timestamp: 1761790814710 +- conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-22.0.0-h7d8d6a5_3_cpu.conda + build_number: 3 + sha256: 9875a4a02ccbc81a8c844d6b9d813a4143365aa89208288817726ed36e6346a4 + md5: 3f9919740ac1af4985283c463f2a14fb + depends: + - libarrow 22.0.0 h0832232_3_cpu + - libarrow-acero 22.0.0 h7d8d6a5_3_cpu + - libarrow-compute 22.0.0 h2db994a_3_cpu + - libparquet 22.0.0 h7051d1f_3_cpu + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 430593 + timestamp: 1762051828631 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-22.0.0-h3f74fd7_3_cpu.conda + build_number: 3 + sha256: 2d653993724e69005be9b112f153e16c15b35d9cd543e7e66290937176419c3e + md5: 46dab35d069968d2b0147a75d78059db + depends: + - __glibc >=2.17,<3.0.a0 + - libabseil * cxx17* + - libabseil >=20250512.1,<20250513.0a0 + - libarrow 22.0.0 h99e40f8_3_cpu + - libarrow-acero 22.0.0 h635bf11_3_cpu + - libarrow-dataset 22.0.0 h635bf11_3_cpu + - libgcc >=14 + - libprotobuf >=6.31.1,<6.31.2.0a0 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 481791 + timestamp: 1761789900880 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-substrait-22.0.0-h4653b8a_3_cpu.conda + build_number: 3 + sha256: 49a920fb82643a9d80c2134e53e33048ed6b9a34b1cfdb9023f245c84e87ba22 + md5: a0c8804a293e8884603729460732a6ba + depends: + - __osx >=11.0 + - libabseil * cxx17* + - libabseil >=20250512.1,<20250513.0a0 + - libarrow 22.0.0 hb95b15f_3_cpu + - libarrow-acero 22.0.0 h2db2d7d_3_cpu + - libarrow-dataset 22.0.0 h2db2d7d_3_cpu + - libcxx >=19 + - libprotobuf >=6.31.1,<6.31.2.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 447691 + timestamp: 1761790939224 +- conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-substrait-22.0.0-hf865cc0_3_cpu.conda + build_number: 3 + sha256: 90259f086d83cdd14704f7a79e2883b8f1d8ba8d5b2e4aa2d73f76a1451ef21d + md5: c5ca32835f04c27585e9e6d28f76de9a + depends: - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libarrow 20.0.0 hc090743_7_cpu - - libarrow-acero 20.0.0 h7d8d6a5_7_cpu - - libarrow-dataset 20.0.0 h7d8d6a5_7_cpu - - libprotobuf >=5.29.3,<5.29.4.0a0 + - libabseil >=20250512.1,<20250513.0a0 + - libarrow 22.0.0 h0832232_3_cpu + - libarrow-acero 22.0.0 h7d8d6a5_3_cpu + - libarrow-dataset 22.0.0 h7d8d6a5_3_cpu + - libprotobuf >=6.31.1,<6.31.2.0a0 - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: APACHE purls: [] - size: 367348 - timestamp: 1749950915126 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-32_h59b9bed_openblas.conda - build_number: 32 - sha256: 1540bf739feb446ff71163923e7f044e867d163c50b605c8b421c55ff39aa338 - md5: 2af9f3d5c2e39f417ce040f5a35c40c6 + size: 358455 + timestamp: 1762051870178 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-38_h4a7cf45_openblas.conda + build_number: 38 + sha256: b26a32302194e05fa395d5135699fd04a905c6ad71f24333f97c64874e053623 + md5: 3509b5e2aaa5f119013c8969fdd9a905 depends: - libopenblas >=0.3.30,<0.3.31.0a0 - libopenblas >=0.3.30,<1.0a0 constrains: - - libcblas 3.9.0 32*_openblas - - mkl <2025 - - liblapacke 3.9.0 32*_openblas - - blas 2.132 openblas - - liblapack 3.9.0 32*_openblas + - libcblas 3.9.0 38*_openblas + - blas 2.138 openblas + - liblapacke 3.9.0 38*_openblas + - mkl <2026 + - liblapack 3.9.0 38*_openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17330 - timestamp: 1750388798074 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-32_h7f60823_openblas.conda - build_number: 32 - sha256: e441fcc46858a9a073e4344c80e267aee3b95ec01b02e37205c36be79eec0694 - md5: 0f7197e3b4ecfa8aa24a371c3eaabb8a + size: 17522 + timestamp: 1761680084434 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-38_he492b99_openblas.conda + build_number: 38 + sha256: 7005975d45fc0538d539f01760cba9132b8b341d4ee833dd2d3133ef6c19d7a9 + md5: 96fcc4cb2feb80ab291bab0316ef3cbc depends: - libopenblas >=0.3.30,<0.3.31.0a0 - libopenblas >=0.3.30,<1.0a0 constrains: - - liblapack 3.9.0 32*_openblas - - blas 2.132 openblas - - mkl <2025 - - liblapacke 3.9.0 32*_openblas - - libcblas 3.9.0 32*_openblas + - mkl <2026 + - libcblas 3.9.0 38*_openblas + - blas 2.138 openblas + - liblapack 3.9.0 38*_openblas + - liblapacke 3.9.0 38*_openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17571 - timestamp: 1750389030403 -- conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-32_h641d27c_mkl.conda - build_number: 32 - sha256: 809d78b096e70fed7ebb17c867dd5dde2f9f4ed8564967a6e10c65b3513b0c31 - md5: 49b36a01450e96c516bbc5486d4a0ea0 + size: 17666 + timestamp: 1761680501294 +- conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-38_hf2e6a31_mkl.conda + build_number: 38 + sha256: 363920dbd6a4c09f419a4e032568d5468dc9196e8c9e401af4e8026ecf88f2b7 + md5: dcee15907da751895e20b4d1ac94568d depends: - - mkl 2024.2.2 h66d3029_15 + - mkl >=2025.3.0,<2026.0a0 constrains: - - libcblas 3.9.0 32*_mkl - - liblapack 3.9.0 32*_mkl - - liblapacke 3.9.0 32*_mkl - - blas 2.132 mkl + - blas 2.138 mkl + - liblapacke 3.9.0 38*_mkl + - libcblas 3.9.0 38*_mkl + - liblapack 3.9.0 38*_mkl license: BSD-3-Clause license_family: BSD purls: [] - size: 3735390 - timestamp: 1750389080409 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_3.conda - sha256: 462a8ed6a7bb9c5af829ec4b90aab322f8bcd9d8987f793e6986ea873bbd05cf - md5: cb98af5db26e3f482bebb80ce9d947d3 + size: 66706 + timestamp: 1761680784374 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-h09219d5_0.conda + sha256: fbbcd11742bb8c96daa5f4f550f1804a902708aad2092b39bec3faaa2c8ae88a + md5: 9b3117ec960b823815b02190b41c0484 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 69233 - timestamp: 1749230099545 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.1.0-h6e16a3a_3.conda - sha256: 23952b1dc3cd8be168995da2d7cc719dac4f2ec5d478ba4c65801681da6f9f52 - md5: ec21ca03bcc08f89b7e88627ae787eaf + size: 79664 + timestamp: 1761592192478 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h105ed1c_0.conda + sha256: 2e6cadb4c044765ba249e019aa0f8d12a2a520600e783a4aa144d660c7bdd7db + md5: 61c2b02435758f1c6926b3733d34ea08 depends: - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 67817 - timestamp: 1749230267706 -- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.1.0-h2466b09_3.conda - sha256: e70ea4b773fadddda697306a80a29d9cbd36b7001547cd54cbfe9a97a518993f - md5: cf20c8b8b48ab5252ec64b9c66bfe0a4 + size: 78540 + timestamp: 1761592885103 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hc82b238_0.conda + sha256: 938078532c3a09e9687747fa562c08ece4a35545467ec26e5be9265a5dbff928 + md5: a5607006c2135402ca3bb96ff9b87896 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: [] - size: 71289 - timestamp: 1749230827419 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb9d3cd8_3.conda - sha256: 3eb27c1a589cbfd83731be7c3f19d6d679c7a444c3ba19db6ad8bf49172f3d83 - md5: 1c6eecffad553bde44c5238770cfb7da + size: 81753 + timestamp: 1761592584940 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hd53d788_0.conda + sha256: f7f357c33bd10afd58072ad4402853a8522d52d00d7ae9adb161ecf719f63574 + md5: c183787d2b228775dece45842abbbe53 depends: - __glibc >=2.17,<3.0.a0 - - libbrotlicommon 1.1.0 hb9d3cd8_3 - - libgcc >=13 + - libbrotlicommon 1.2.0 h09219d5_0 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 33148 - timestamp: 1749230111397 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.1.0-h6e16a3a_3.conda - sha256: 499374a97637e4c6da0403ced7c9860d25305c6cb92c70dded738134c4973c67 - md5: 71d03e5e44801782faff90c455b3e69a + size: 34445 + timestamp: 1761592202559 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h660c9da_0.conda + sha256: 13550c1a8ffe2e77b23febcadacf6e3818ea7a0a1969edc740b87bc1d9760bf7 + md5: c8f29cbebccb17826d805c15282c7e8b depends: - __osx >=10.13 - - libbrotlicommon 1.1.0 h6e16a3a_3 + - libbrotlicommon 1.2.0 h105ed1c_0 license: MIT license_family: MIT purls: [] - size: 30627 - timestamp: 1749230291245 -- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.1.0-h2466b09_3.conda - sha256: a35a0db7e3257e011b10ffb371735b2b24074412d0b27c3dab7ca9f2c549cfcf - md5: a342933dbc6d814541234c7c81cb5205 + size: 30767 + timestamp: 1761592911771 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-h431afc6_0.conda + sha256: 229edc6f56b51dde812d1932b4c6f477654c2f5d477fff9cff184ebd4ce158bd + md5: edc47a5d0ec6d95efefab3e99d0f4df0 depends: - - libbrotlicommon 1.1.0 h2466b09_3 + - libbrotlicommon 1.2.0 hc82b238_0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: [] - size: 33451 - timestamp: 1749230869051 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_3.conda - sha256: 76e8492b0b0a0d222bfd6081cae30612aa9915e4309396fdca936528ccf314b7 - md5: 3facafe58f3858eb95527c7d3a3fc578 + size: 34299 + timestamp: 1761592621800 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-h02bd7ab_0.conda + sha256: 1370c8b1a215751c4592bf95d4b5d11bac91c577770efcb237e3a0f35c326559 + md5: b7a924e3e9ebc7938ffc7d94fe603ed3 depends: - __glibc >=2.17,<3.0.a0 - - libbrotlicommon 1.1.0 hb9d3cd8_3 - - libgcc >=13 + - libbrotlicommon 1.2.0 h09219d5_0 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 282657 - timestamp: 1749230124839 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.1.0-h6e16a3a_3.conda - sha256: e6d7a42fe87a23df03c482c885e428cc965d1628f18e5cee47575f6216c7fbc5 - md5: 94c0090989db51216f40558958a3dd40 + size: 298252 + timestamp: 1761592214576 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h2338291_0.conda + sha256: 195b092bc924f050c95ff950109babb9bb05ad0ad293e07783fdfe9e0daeae8c + md5: 57b746e8ed03d56fe908fd050c517299 depends: - __osx >=10.13 - - libbrotlicommon 1.1.0 h6e16a3a_3 + - libbrotlicommon 1.2.0 h105ed1c_0 license: MIT license_family: MIT purls: [] - size: 295250 - timestamp: 1749230310752 -- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.1.0-h2466b09_3.conda - sha256: 9d0703c5a01c10d346587ff0535a0eb81042364333caa4a24a0e4a0c08fd490b - md5: 7ef0af55d70cbd9de324bb88b7f9d81e + size: 310340 + timestamp: 1761592941136 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-ha521d6b_0.conda + sha256: eb54110ee720e4a73b034d0c2bb0f26eadf79a1bd6b0656ebdf914da8f14989d + md5: f780291507a3f91d93a7147daea082f8 depends: - - libbrotlicommon 1.1.0 h2466b09_3 + - libbrotlicommon 1.2.0 hc82b238_0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: [] - size: 245845 - timestamp: 1749230909225 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-32_he106b2a_openblas.conda - build_number: 32 - sha256: 92a001fc181e6abe4f4a672b81d9413ca2f22609f8a95327dfcc6eee593ffeb9 - md5: 3d3f9355e52f269cd8bc2c440d8a5263 + size: 253172 + timestamp: 1761592654725 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-38_h0358290_openblas.conda + build_number: 38 + sha256: 7fe653f45c01eb16d7b48ad934b068dad2885d6f4a7c41512b6a5f1f522bffe9 + md5: bcd928a9376a215cd9164a4312dd5e98 depends: - - libblas 3.9.0 32_h59b9bed_openblas + - libblas 3.9.0 38_h4a7cf45_openblas constrains: - - blas 2.132 openblas - - liblapack 3.9.0 32*_openblas - - liblapacke 3.9.0 32*_openblas + - blas 2.138 openblas + - liblapack 3.9.0 38*_openblas + - liblapacke 3.9.0 38*_openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17308 - timestamp: 1750388809353 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-32_hff6cab4_openblas.conda - build_number: 32 - sha256: 745f6dd420389809c333734df6edc99d75caa3633e4778158c7549c6844af440 - md5: 2c1e774d4546cf542eaee5781eb8940b + size: 17503 + timestamp: 1761680091587 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-38_h9b27e0a_openblas.conda + build_number: 38 + sha256: b7c393080aea5518cb87a1f1e44fd1b29f1564cf5f2610a2ddb575e582396779 + md5: 3fd79655bb102d44663e5b6c84a526a8 depends: - - libblas 3.9.0 32_h7f60823_openblas + - libblas 3.9.0 38_he492b99_openblas constrains: - - blas 2.132 openblas - - liblapack 3.9.0 32*_openblas - - liblapacke 3.9.0 32*_openblas + - blas 2.138 openblas + - liblapack 3.9.0 38*_openblas + - liblapacke 3.9.0 38*_openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17574 - timestamp: 1750389040732 -- conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-32_h5e41251_mkl.conda - build_number: 32 - sha256: d0f81145ae795592f3f3b5d7ff641c1019a99d6b308bfaf2a4cc5ba24b067bb0 - md5: 054b9b4b48296e4413cf93e6ece7b27d + size: 17667 + timestamp: 1761680519380 +- conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-38_h2a3cdd5_mkl.conda + build_number: 38 + sha256: f2bec12b960877387e5e8f84af5a50e19e97f52ddb1bed6b93ea38c4fb18ab62 + md5: 0c1602b1d15eb3d4da15bad122740df8 depends: - - libblas 3.9.0 32_h641d27c_mkl + - libblas 3.9.0 38_hf2e6a31_mkl constrains: - - liblapack 3.9.0 32*_mkl - - liblapacke 3.9.0 32*_mkl - - blas 2.132 mkl + - blas 2.138 mkl + - liblapacke 3.9.0 38*_mkl + - liblapack 3.9.0 38*_mkl license: BSD-3-Clause license_family: BSD purls: [] - size: 3735392 - timestamp: 1750389122586 + size: 67055 + timestamp: 1761680819734 - conda: https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2 sha256: fd1d153962764433fe6233f34a72cdeed5dcf8a883a85769e8295ce940b5b0c5 md5: c965a5aa0d5c1c37ffc62dff36e28400 @@ -4784,97 +4917,97 @@ packages: purls: [] size: 25694 timestamp: 1633684287072 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.14.1-h332b0f4_0.conda - sha256: b6c5cf340a4f80d70d64b3a29a7d9885a5918d16a5cb952022820e6d3e79dc8b - md5: 45f6713cb00f124af300342512219182 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_0.conda + sha256: 100e29ca864c32af15a5cc354f502d07b2600218740fdf2439fa7d66b50b3529 + md5: 01e149d4a53185622dc2e788281961f2 depends: - __glibc >=2.17,<3.0.a0 - krb5 >=1.21.3,<1.22.0a0 - - libgcc >=13 - - libnghttp2 >=1.64.0,<2.0a0 + - libgcc >=14 + - libnghttp2 >=1.67.0,<2.0a0 - libssh2 >=1.11.1,<2.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 + - openssl >=3.5.4,<4.0a0 - zstd >=1.5.7,<1.6.0a0 license: curl license_family: MIT purls: [] - size: 449910 - timestamp: 1749033146806 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.14.1-h5dec5d8_0.conda - sha256: ca0d8d12056227d6b47122cfb6d68fc5a3a0c6ab75a0e908542954fc5f84506c - md5: 8738cd19972c3599400404882ddfbc24 + size: 460366 + timestamp: 1762333743748 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.17.0-h7dd4100_0.conda + sha256: a58ca5a28c1cb481f65800781cee9411bd68e8bda43a69817aaeb635d25f7d75 + md5: b3985ef7ca4cd2db59756bae2963283a depends: - __osx >=10.13 - krb5 >=1.21.3,<1.22.0a0 - - libnghttp2 >=1.64.0,<2.0a0 + - libnghttp2 >=1.67.0,<2.0a0 - libssh2 >=1.11.1,<2.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 + - openssl >=3.5.4,<4.0a0 - zstd >=1.5.7,<1.6.0a0 license: curl license_family: MIT purls: [] - size: 424040 - timestamp: 1749033558114 -- conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.14.1-h88aaa65_0.conda - sha256: b2cface2cf35d8522289df7fffc14370596db6f6dc481cc1b6ca313faeac19d8 - md5: 836b9c08f34d2017dbcaec907c6a1138 + size: 412858 + timestamp: 1762334472915 +- conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.17.0-h43ecb02_0.conda + sha256: 651daa5d2bad505b5c72b1d5d4d8c7fc0776ab420e67af997ca9391b6854b1b3 + md5: cfade9be135edb796837e7d4c288c0fb depends: - krb5 >=1.21.3,<1.22.0a0 - libssh2 >=1.11.1,<2.0a0 - libzlib >=1.3.1,<2.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: curl license_family: MIT purls: [] - size: 368346 - timestamp: 1749033492826 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-20.1.7-hf95d169_0.conda - sha256: f6e088a2e0e702a4908d1fc9f1a17b080bdcf63e1f8a9cb35dd158fc1d1eb2f5 - md5: 8b47ade37d4e75417b4e993179c09f5d + size: 378897 + timestamp: 1762333969177 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.5-h3d58e20_0.conda + sha256: 2471cbb0741494aeb1706ad4593a9b993bbcb9c874518833c08073623b958359 + md5: d76e25c022d8dddc2055b981fa78a7e7 depends: - __osx >=10.13 license: Apache-2.0 WITH LLVM-exception license_family: Apache purls: [] - size: 562573 - timestamp: 1749846921724 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda - sha256: 8420748ea1cc5f18ecc5068b4f24c7a023cc9b20971c99c824ba10641fb95ddf - md5: 64f0c503da58ec25ebd359e4d990afa8 + size: 569679 + timestamp: 1762257632306 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda + sha256: aa8e8c4be9a2e81610ddf574e05b64ee131fab5e0e3693210c9d6d2fba32c680 + md5: 6c77a605a7a689d17d4819c0f8ac9a00 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 72573 - timestamp: 1747040452262 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.24-hcc1b750_0.conda - sha256: 2733a4adf53daca1aa4f41fe901f0f8ee9e4c509abd23ffcd7660013772d6f45 - md5: f0a46c359722a3e84deb05cd4072d153 + size: 73490 + timestamp: 1761979956660 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda + sha256: 025f8b1e85dd8254e0ca65f011919fb1753070eb507f03bca317871a884d24de + md5: 31aa65919a729dc48180893f62c25221 depends: - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 69751 - timestamp: 1747040526774 -- conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.24-h76ddb4d_0.conda - sha256: 65347475c0009078887ede77efe60db679ea06f2b56f7853b9310787fe5ad035 - md5: 08d988e266c6ae77e03d164b83786dc4 + size: 70840 + timestamp: 1761980008502 +- conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda + sha256: 834e4881a18b690d5ec36f44852facd38e13afe599e369be62d29bd675f107ee + md5: e77030e67343e28b084fabd7db0ce43e depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: [] - size: 156292 - timestamp: 1747040812624 + size: 156818 + timestamp: 1761979842440 - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 md5: c277e0a4d549b03ac1e9d6cbbe3d017b @@ -4952,262 +5085,262 @@ packages: purls: [] size: 410555 timestamp: 1685726568668 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda - sha256: 33ab03438aee65d6aa667cf7d90c91e5e7d734c19a67aa4c7040742c0a13d505 - md5: db0bfbe7dd197b68ad5f30333bae6ce0 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda + sha256: da2080da8f0288b95dd86765c801c6e166c4619b910b11f9a8446fb852438dc2 + md5: 4211416ecba1866fab0c6470986c22d6 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 constrains: - - expat 2.7.0.* + - expat 2.7.1.* license: MIT license_family: MIT purls: [] - size: 74427 - timestamp: 1743431794976 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.0-h240833e_0.conda - sha256: 976f2e23ad2bb2b8e92c99bfa2ead3ad557b17a129b170f7e2dfcf233193dd7e - md5: 026d0a1056ba2a3dbbea6d4b08188676 + size: 74811 + timestamp: 1752719572741 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.1-h21dd04a_0.conda + sha256: 689862313571b62ee77ee01729dc093f2bf25a2f99415fcfe51d3a6cd31cce7b + md5: 9fdeae0b7edda62e989557d645769515 depends: - __osx >=10.13 constrains: - - expat 2.7.0.* + - expat 2.7.1.* license: MIT license_family: MIT purls: [] - size: 71894 - timestamp: 1743431912423 -- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.0-he0c23c2_0.conda - sha256: 1a227c094a4e06bd54e8c2f3ec40c17ff99dcf3037d812294f842210aa66dbeb - md5: b6f5352fdb525662f4169a0431d2dd7a + size: 72450 + timestamp: 1752719744781 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.1-hac47afa_0.conda + sha256: 8432ca842bdf8073ccecf016ccc9140c41c7114dc4ec77ca754551c01f780845 + md5: 3608ffde260281fa641e70d6e34b1b96 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - - expat 2.7.0.* + - expat 2.7.1.* license: MIT license_family: MIT purls: [] - size: 140896 - timestamp: 1743432122520 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - sha256: 764432d32db45466e87f10621db5b74363a9f847d2b8b1f9743746cd160f06ab - md5: ede4673863426c0883c0063d853bbd85 + size: 141322 + timestamp: 1752719767870 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda + sha256: 25cbdfa65580cfab1b8d15ee90b4c9f1e0d72128f1661449c9a999d341377d54 + md5: 35f29eec58405aaf55e01cb470d8c26a depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 57433 - timestamp: 1743434498161 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.6-h281671d_1.conda - sha256: 6394b1bc67c64a21a5cc73d1736d1d4193a64515152e861785c44d2cfc49edf3 - md5: 4ca9ea59839a9ca8df84170fab4ceb41 + size: 57821 + timestamp: 1760295480630 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda + sha256: 277dc89950f5d97f1683f26e362d6dca3c2efa16cb2f6fdb73d109effa1cd3d0 + md5: d214916b24c625bcc459b245d509f22e depends: - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 51216 - timestamp: 1743434595269 -- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda - sha256: d3b0b8812eab553d3464bbd68204f007f1ebadf96ce30eb0cbc5159f72e353f5 - md5: 85d8fa5e55ed8f93f874b3b23ed54ec6 + size: 52573 + timestamp: 1760295626449 +- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda + sha256: ddff25aaa4f0aa535413f5d831b04073789522890a4d8626366e43ecde1534a3 + md5: ba4ad812d2afc22b9a34ce8327a0930f depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: [] - size: 44978 - timestamp: 1743435053850 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda - sha256: 7be9b3dac469fe3c6146ff24398b685804dfc7a1de37607b84abd076f57cc115 - md5: 51f5be229d83ecd401fb369ab96ae669 + size: 44866 + timestamp: 1760295760649 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda + sha256: 4641d37faeb97cf8a121efafd6afd040904d4bca8c46798122f417c31d5dfbec + md5: f4084e4e6577797150f9b04a4560ceb0 depends: - - libfreetype6 >=2.13.3 + - libfreetype6 >=2.14.1 license: GPL-2.0-only OR FTL purls: [] - size: 7693 - timestamp: 1745369988361 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.13.3-h694c41f_1.conda - sha256: afe0e2396844c8cfdd6256ac84cabc9af823b1727f704c137b030b85839537a6 - md5: 07c8d3fbbe907f32014b121834b36dd5 + size: 7664 + timestamp: 1757945417134 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.1-h694c41f_0.conda + sha256: 035e23ef87759a245d51890aedba0b494a26636784910c3730d76f3dc4482b1d + md5: e0e2edaf5e0c71b843e25a7ecc451cc9 depends: - - libfreetype6 >=2.13.3 + - libfreetype6 >=2.14.1 license: GPL-2.0-only OR FTL purls: [] - size: 7805 - timestamp: 1745370212559 -- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.13.3-h57928b3_1.conda - sha256: e5bc7d0a8d11b7b234da4fcd9d78f297f7dec3fec8bd06108fd3ac7b2722e32e - md5: 410ba2c8e7bdb278dfbb5d40220e39d2 + size: 7780 + timestamp: 1757945952392 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.1-h57928b3_0.conda + sha256: 2029702ec55e968ce18ec38cc8cf29f4c8c4989a0d51797164dab4f794349a64 + md5: 3235024fe48d4087721797ebd6c9d28c depends: - - libfreetype6 >=2.13.3 + - libfreetype6 >=2.14.1 license: GPL-2.0-only OR FTL purls: [] - size: 8159 - timestamp: 1745370227235 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda - sha256: 7759bd5c31efe5fbc36a7a1f8ca5244c2eabdbeb8fc1bee4b99cf989f35c7d81 - md5: 3c255be50a506c50765a93a6644f32fe + size: 8109 + timestamp: 1757946135015 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda + sha256: 4a7af818a3179fafb6c91111752954e29d3a2a950259c14a2fc7ba40a8b03652 + md5: 8e7251989bca326a28f4a5ffbd74557a depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libpng >=1.6.47,<1.7.0a0 + - libgcc >=14 + - libpng >=1.6.50,<1.7.0a0 - libzlib >=1.3.1,<2.0a0 constrains: - - freetype >=2.13.3 + - freetype >=2.14.1 license: GPL-2.0-only OR FTL purls: [] - size: 380134 - timestamp: 1745369987697 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.13.3-h40dfd5c_1.conda - sha256: 058165962aa64fc5a6955593212c0e1ea42ca6d6dba60ee61dff612d4c3818d7 - md5: c76e6f421a0e95c282142f820835e186 + size: 386739 + timestamp: 1757945416744 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.1-h6912278_0.conda + sha256: f5f28092e368efc773bcd1c381d123f8b211528385a9353e36f8808d00d11655 + md5: dfbdc8fd781dc3111541e4234c19fdbd depends: - __osx >=10.13 - - libpng >=1.6.47,<1.7.0a0 + - libpng >=1.6.50,<1.7.0a0 - libzlib >=1.3.1,<2.0a0 constrains: - - freetype >=2.13.3 + - freetype >=2.14.1 license: GPL-2.0-only OR FTL purls: [] - size: 357654 - timestamp: 1745370210187 -- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.13.3-h0b5ce68_1.conda - sha256: 61308653e7758ff36f80a60d598054168a1389ddfbac46d7864c415fafe18e69 - md5: a84b7d1a13060a9372bea961a8131dbc + size: 374993 + timestamp: 1757945949585 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda + sha256: 223710600b1a5567163f7d66545817f2f144e4ef8f84e99e90f6b8a4e19cb7ad + md5: 6e7c5c5ab485057b5d07fd8188ba5c28 depends: - - libpng >=1.6.47,<1.7.0a0 + - libpng >=1.6.50,<1.7.0a0 - libzlib >=1.3.1,<2.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - - freetype >=2.13.3 + - freetype >=2.14.1 license: GPL-2.0-only OR FTL purls: [] - size: 337007 - timestamp: 1745370226578 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda - sha256: 0024f9ab34c09629621aefd8603ef77bf9d708129b0dd79029e502c39ffc2195 - md5: ea8ac52380885ed41c1baa8f1d6d2b93 + size: 340264 + timestamp: 1757946133889 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda + sha256: 08f9b87578ab981c7713e4e6a7d935e40766e10691732bba376d4964562bcb45 + md5: c0374badb3a5d4b1372db28d19462c53 depends: - __glibc >=2.17,<3.0.a0 - _openmp_mutex >=4.5 constrains: - - libgcc-ng ==15.1.0=*_2 - - libgomp 15.1.0 h767d61c_2 + - libgomp 15.2.0 h767d61c_7 + - libgcc-ng ==15.2.0=*_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 829108 - timestamp: 1746642191935 -- conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.1.0-h1383e82_2.conda - sha256: c0288596ac58366d96a56c57e4088fe1c6dd4194fdcaeacf5862f47fb1e1e5be - md5: 9bedb24480136bfeb81ebc81d4285e70 + size: 822552 + timestamp: 1759968052178 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h1383e82_7.conda + sha256: 174c4c75b03923ac755f227c96d956f7b4560a4b7dd83c0332709c50ff78450f + md5: 926a82fc4fa5b284b1ca1fb74f20dee2 depends: - _openmp_mutex >=4.5 - libwinpthread >=12.0.0.r4.gg4f2fc60ca constrains: - msys2-conda-epoch <0.0a0 - - libgcc-ng ==15.1.0=*_2 - - libgomp 15.1.0 h1383e82_2 + - libgomp 15.2.0 h1383e82_7 + - libgcc-ng ==15.2.0=*_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 673459 - timestamp: 1746656621653 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda - sha256: 0ab5421a89f090f3aa33841036bb3af4ed85e1f91315b528a9d75fab9aad51ae - md5: ddca86c7040dd0e73b2b69bd7833d225 + size: 667897 + timestamp: 1759976063036 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda + sha256: 2045066dd8e6e58aaf5ae2b722fb6dfdbb57c862b5f34ac7bfb58c40ef39b6ad + md5: 280ea6eee9e2ddefde25ff799c4f0363 depends: - - libgcc 15.1.0 h767d61c_2 + - libgcc 15.2.0 h767d61c_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 34586 - timestamp: 1746642200749 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_2.conda - sha256: 914daa4f632b786827ea71b5e07cd00d25fc6e67789db2f830dc481eec660342 - md5: f92e6e0a3c0c0c85561ef61aa59d555d + size: 29313 + timestamp: 1759968065504 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda + sha256: 9ca24328e31c8ef44a77f53104773b9fe50ea8533f4c74baa8489a12de916f02 + md5: 8621a450add4e231f676646880703f49 depends: - - libgfortran5 15.1.0 hcea5267_2 + - libgfortran5 15.2.0 hcd61629_7 constrains: - - libgfortran-ng ==15.1.0=*_2 + - libgfortran-ng ==15.2.0=*_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 34541 - timestamp: 1746642233221 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-5.0.0-14_2_0_h51e75f0_103.conda - sha256: 124dcd89508bd16f562d9d3ce6a906336a7f18e963cd14f2877431adee14028e - md5: 090b3c9ae1282c8f9b394ac9e4773b10 + size: 29275 + timestamp: 1759968110483 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h306097a_1.conda + sha256: 97551952312cf4954a7ad6ba3fd63c739eac65774fe96ddd121c67b5196a8689 + md5: cd5393330bff47a00d37a117c65b65d0 depends: - - libgfortran5 14.2.0 h51e75f0_103 + - libgfortran5 15.2.0 h336fb69_1 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 156202 - timestamp: 1743862427451 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_2.conda - sha256: be23750f3ca1a5cb3ada858c4f633effe777487d1ea35fddca04c0965c073350 - md5: 01de444988ed960031dbe84cf4f9b1fc + size: 134506 + timestamp: 1759710031253 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda + sha256: e93ceda56498d98c9f94fedec3e2d00f717cbedfc97c49be0e5a5828802f2d34 + md5: f116940d825ffc9104400f0d7f1a4551 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=15.1.0 + - libgcc >=15.2.0 constrains: - - libgfortran 15.1.0 + - libgfortran 15.2.0 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 1569986 - timestamp: 1746642212331 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-14.2.0-h51e75f0_103.conda - sha256: d2ac5e09587e5b21b7bb5795d24f33257e44320749c125448611211088ef8795 - md5: 6183f7e9cd1e7ba20118ff0ca20a05e5 + size: 1572758 + timestamp: 1759968082504 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-h336fb69_1.conda + sha256: 1d53bad8634127b3c51281ce6ad3fbf00f7371824187490a36e5182df83d6f37 + md5: b6331e2dcc025fc79cd578f4c181d6f2 depends: - llvm-openmp >=8.0.0 constrains: - - libgfortran 5.0.0 14_2_0_*_103 + - libgfortran 15.2.0 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 1225013 - timestamp: 1743862382377 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.2-h3618099_0.conda - sha256: a6b5cf4d443044bc9a0293dd12ca2015f0ebe5edfdc9c4abdde0b9947f9eb7bd - md5: 072ab14a02164b7c0c089055368ff776 + size: 1236316 + timestamp: 1759709318982 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.1-h32235b2_2.conda + sha256: fc82277d0d6340743732c48dcbac3f4e9ee36902649a7d9a02622b0713ce3666 + md5: 986dcf488a1aced411da84753d93d078 depends: - __glibc >=2.17,<3.0.a0 - - libffi >=3.4.6,<3.5.0a0 - - libgcc >=13 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 - libiconv >=1.18,<2.0a0 - libzlib >=1.3.1,<2.0a0 - - pcre2 >=10.45,<10.46.0a0 + - pcre2 >=10.46,<10.47.0a0 constrains: - - glib 2.84.2 *_0 + - glib 2.86.1 *_2 license: LGPL-2.1-or-later purls: [] - size: 3955066 - timestamp: 1747836671118 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_2.conda - sha256: 05fff3dc7e80579bc28de13b511baec281c4343d703c406aefd54389959154fb - md5: fbe7d535ff9d3a168c148e07358cd5b1 + size: 3933707 + timestamp: 1762787455198 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda + sha256: e9fb1c258c8e66ee278397b5822692527c5f5786d372fe7a869b900853f3f5ca + md5: f7b4d76975aac7e5d9e6ad13845f92fe depends: - __glibc >=2.17,<3.0.a0 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 452635 - timestamp: 1746642113092 -- conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.1.0-h1383e82_2.conda - sha256: 4316316097ce5fde2608b6fccd18709cf647dce52e230f5ac66f5c524dfad791 - md5: 5fbacaa9b41e294a6966602205b99747 + size: 447919 + timestamp: 1759967942498 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h1383e82_7.conda + sha256: b8b569a9d3ec8f13531c220d3ad8e1ff35c75902c89144872e7542a77cb8c10d + md5: 7f970a7f9801622add7746aa3cbc24d5 depends: - libwinpthread >=12.0.0.r4.gg4f2fc60ca constrains: @@ -5215,308 +5348,309 @@ packages: license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 540903 - timestamp: 1746656563815 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.36.0-hc4361e1_1.conda - sha256: 3a56c653231d6233de5853dc01f07afad6a332799a39c3772c0948d2e68547e4 - md5: ae36e6296a8dd8e8a9a8375965bf6398 + size: 535898 + timestamp: 1759975963604 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda + sha256: d3341cf69cb02c07bbd1837968f993da01b7bd467e816b1559a3ca26c1ff14c5 + md5: a2e30ccd49f753fd30de0d30b1569789 depends: - __glibc >=2.17,<3.0.a0 - libabseil * cxx17* - - libabseil >=20250127.0,<20250128.0a0 - - libcurl >=8.12.1,<9.0a0 - - libgcc >=13 - - libgrpc >=1.71.0,<1.72.0a0 - - libprotobuf >=5.29.3,<5.29.4.0a0 - - libstdcxx >=13 - - openssl >=3.4.1,<4.0a0 + - libabseil >=20250512.1,<20250513.0a0 + - libcurl >=8.14.1,<9.0a0 + - libgcc >=14 + - libgrpc >=1.73.1,<1.74.0a0 + - libprotobuf >=6.31.1,<6.31.2.0a0 + - libstdcxx >=14 + - openssl >=3.5.1,<4.0a0 constrains: - - libgoogle-cloud 2.36.0 *_1 + - libgoogle-cloud 2.39.0 *_0 license: Apache-2.0 license_family: Apache purls: [] - size: 1246764 - timestamp: 1741878603939 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libgoogle-cloud-2.36.0-h777fda5_1.conda - sha256: 4de9069f3f1d679b8e14bf9a091bf51f52fb83453e1657d65d22b4a129c9447a - md5: 0002a344f6b7d5cba07a6597a0486eef + size: 1307909 + timestamp: 1752048413383 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgoogle-cloud-2.39.0-hed66dea_0.conda + sha256: 9b50362bafd60c4a3eb6c37e6dbf7e200562dab7ae1b282b1ebd633d4d77d4bd + md5: 06564befaabd2760dfa742e47074bad2 depends: - - __osx >=10.14 + - __osx >=11.0 - libabseil * cxx17* - - libabseil >=20250127.0,<20250128.0a0 - - libcurl >=8.12.1,<9.0a0 - - libcxx >=18 - - libgrpc >=1.71.0,<1.72.0a0 - - libprotobuf >=5.29.3,<5.29.4.0a0 - - openssl >=3.4.1,<4.0a0 + - libabseil >=20250512.1,<20250513.0a0 + - libcurl >=8.14.1,<9.0a0 + - libcxx >=19 + - libgrpc >=1.73.1,<1.74.0a0 + - libprotobuf >=6.31.1,<6.31.2.0a0 + - openssl >=3.5.1,<4.0a0 constrains: - - libgoogle-cloud 2.36.0 *_1 + - libgoogle-cloud 2.39.0 *_0 license: Apache-2.0 license_family: Apache purls: [] - size: 894617 - timestamp: 1741879322948 -- conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-2.36.0-hf249c01_1.conda - sha256: 04baf461a2ebb8e8ac0978a006774124d1a8928e921c3ae4d9c27f072db7b2e2 - md5: 2842dfad9b784ab71293915db73ff093 + size: 899629 + timestamp: 1752048034356 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-2.39.0-h19ee442_0.conda + sha256: 8f5b26e9ea985c819a67e41664da82219534f9b9c8ba190f7d3c440361e5accb + md5: c2c512f98c5c666782779439356a1713 depends: - libabseil * cxx17* - - libabseil >=20250127.0,<20250128.0a0 - - libcurl >=8.12.1,<9.0a0 - - libgrpc >=1.71.0,<1.72.0a0 - - libprotobuf >=5.29.3,<5.29.4.0a0 + - libabseil >=20250512.1,<20250513.0a0 + - libcurl >=8.14.1,<9.0a0 + - libgrpc >=1.73.1,<1.74.0a0 + - libprotobuf >=6.31.1,<6.31.2.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - - libgoogle-cloud 2.36.0 *_1 + - libgoogle-cloud 2.39.0 *_0 license: Apache-2.0 license_family: Apache purls: [] - size: 14643 - timestamp: 1741878994528 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.36.0-h0121fbd_1.conda - sha256: 54235d990009417bb20071f5ce7c8dcf186b19fa7d24d72bc5efd2ffb108001c - md5: a0f7588c1f0a26d550e7bae4fb49427a + size: 14952 + timestamp: 1752049549178 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda + sha256: 59eb8365f0aee384f2f3b2a64dcd454f1a43093311aa5f21a8bb4bd3c79a6db8 + md5: bd21962ff8a9d1ce4720d42a35a4af40 depends: - __glibc >=2.17,<3.0.a0 - libabseil - libcrc32c >=1.1.2,<1.2.0a0 - libcurl - - libgcc >=13 - - libgoogle-cloud 2.36.0 hc4361e1_1 - - libstdcxx >=13 + - libgcc >=14 + - libgoogle-cloud 2.39.0 hdb79228_0 + - libstdcxx >=14 - libzlib >=1.3.1,<2.0a0 - openssl license: Apache-2.0 license_family: Apache purls: [] - size: 785719 - timestamp: 1741878763994 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libgoogle-cloud-storage-2.36.0-h3397294_1.conda - sha256: 2b294f87a6fe2463db6a0af9ca7a721324aab3711e475c0e28e35f233f624245 - md5: f360c132b279b8a3c3af5c57390524be + size: 804189 + timestamp: 1752048589800 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgoogle-cloud-storage-2.39.0-h8ac052b_0.conda + sha256: fe790fc9ed8ffa468d27e886735fe11844369caee406d98f1da2c0d8aed0401e + md5: 7600fb1377c8eb5a161e4a2520933daa depends: - - __osx >=10.14 + - __osx >=11.0 - libabseil - libcrc32c >=1.1.2,<1.2.0a0 - libcurl - - libcxx >=18 - - libgoogle-cloud 2.36.0 h777fda5_1 + - libcxx >=19 + - libgoogle-cloud 2.39.0 hed66dea_0 - libzlib >=1.3.1,<2.0a0 - openssl license: Apache-2.0 license_family: Apache purls: [] - size: 544276 - timestamp: 1741880880598 -- conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-storage-2.36.0-he5eb982_1.conda - sha256: 0dbdfc80b79bd491f4240c6f6dc6c275d341ea24765ce40f07063a253ad21063 - md5: 8b5af0aa84ff9c2117c1cefc07622800 + size: 543323 + timestamp: 1752048443047 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-storage-2.39.0-he04ea4c_0.conda + sha256: 51c29942d9bb856081605352ac74c45cad4fedbaac89de07c74efb69a3be9ab3 + md5: 26198e3dc20bbcbea8dd6fa5ab7ea1e0 depends: - libabseil - libcrc32c >=1.1.2,<1.2.0a0 - libcurl - - libgoogle-cloud 2.36.0 hf249c01_1 + - libgoogle-cloud 2.39.0 h19ee442_0 - libzlib >=1.3.1,<2.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: Apache purls: [] - size: 14544 - timestamp: 1741879301389 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.71.0-h8e591d7_1.conda - sha256: 37267300b25f292a6024d7fd9331085fe4943897940263c3a41d6493283b2a18 - md5: c3cfd72cbb14113abee7bbd86f44ad69 + size: 14904 + timestamp: 1752049852815 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.73.1-h3288cfb_1.conda + sha256: bc9d32af6167b1f5bcda216dc44eddcb27f3492440571ab12f6e577472a05e34 + md5: ff63bb12ac31c176ff257e3289f20770 depends: - __glibc >=2.17,<3.0.a0 - c-ares >=1.34.5,<2.0a0 - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libgcc >=13 - - libprotobuf >=5.29.3,<5.29.4.0a0 - - libre2-11 >=2024.7.2 - - libstdcxx >=13 + - libabseil >=20250512.1,<20250513.0a0 + - libgcc >=14 + - libprotobuf >=6.31.1,<6.31.2.0a0 + - libre2-11 >=2025.8.12 + - libstdcxx >=14 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 + - openssl >=3.5.4,<4.0a0 - re2 constrains: - - grpc-cpp =1.71.0 + - grpc-cpp =1.73.1 license: Apache-2.0 license_family: APACHE purls: [] - size: 7920187 - timestamp: 1745229332239 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libgrpc-1.71.0-h7d722e6_1.conda - sha256: 304649f99f6cde43cf4fb95cc2892b5955aa31bf3d8b74f707a8ca1347c06b88 - md5: 460e0c0ac50927c2974e41aab9272c6b + size: 8349777 + timestamp: 1761058442526 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgrpc-1.73.1-h451496d_1.conda + sha256: 30378f4c9055224fecd1da8b9a65e2c0293cde68edca0f8a306fd9e92fd6ee1f + md5: d6ea2acfae86b523b54938c6bc30e378 depends: - - __osx >=10.14 + - __osx >=11.0 - c-ares >=1.34.5,<2.0a0 - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libcxx >=18 - - libprotobuf >=5.29.3,<5.29.4.0a0 - - libre2-11 >=2024.7.2 + - libabseil >=20250512.1,<20250513.0a0 + - libcxx >=19 + - libprotobuf >=6.31.1,<6.31.2.0a0 + - libre2-11 >=2025.8.12 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 + - openssl >=3.5.4,<4.0a0 - re2 constrains: - - grpc-cpp =1.71.0 + - grpc-cpp =1.73.1 license: Apache-2.0 license_family: APACHE purls: [] - size: 5510897 - timestamp: 1745201273719 -- conda: https://conda.anaconda.org/conda-forge/win-64/libgrpc-1.71.0-h8c3449c_1.conda - sha256: eb832f8eea6936400753a5344ebce3e09c36698d04becd6ef234fda9c480cccb - md5: ef38e4d5e1814a912311abd4468e90bb + size: 5468625 + timestamp: 1761060387315 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgrpc-1.73.1-h317e13b_1.conda + sha256: 95a83e98c35b8ec03d84f0714eefb2630078d9224360a93dbef6f2403414f76f + md5: 855b10d858d6c078a28d670cf32baa67 depends: - c-ares >=1.34.5,<2.0a0 - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libprotobuf >=5.29.3,<5.29.4.0a0 - - libre2-11 >=2024.7.2 + - libabseil >=20250512.1,<20250513.0a0 + - libprotobuf >=6.31.1,<6.31.2.0a0 + - libre2-11 >=2025.8.12 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 + - openssl >=3.5.4,<4.0a0 - re2 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - - grpc-cpp =1.71.0 + - grpc-cpp =1.73.1 license: Apache-2.0 license_family: APACHE purls: [] - size: 13999413 - timestamp: 1745192535016 -- conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.11.2-default_ha69328c_1001.conda - sha256: 850e255997f538d5fb6ed651321141155a33bb781d43d326fc4ff62114dd2842 - md5: b87a0ac5ab6495d8225db5dc72dd21cd + size: 14433486 + timestamp: 1761053760632 +- conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.1-default_h64bd3f2_1002.conda + sha256: 266dfe151066c34695dbdc824ba1246b99f016115ef79339cbcf005ac50527c1 + md5: b0cac6e5b06ca5eeb14b4f7cf908619f depends: - libwinpthread >=12.0.0.r4.gg4f2fc60ca - - libxml2 >=2.13.4,<2.14.0a0 + - libxml2 + - libxml2-16 >=2.14.6 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: BSD-3-Clause license_family: BSD purls: [] - size: 2390021 - timestamp: 1731375651179 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda - sha256: 18a4afe14f731bfb9cf388659994263904d20111e42f841e9eea1bb6f91f4ab4 - md5: e796ff8ddc598affdf7c173d6145f087 + size: 2414731 + timestamp: 1757624335056 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + sha256: c467851a7312765447155e071752d7bf9bf44d610a5687e32706f480aad2833f + md5: 915f5995e94f60e9a4826e0b0920ee88 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: LGPL-2.1-only purls: [] - size: 713084 - timestamp: 1740128065462 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h4b5e92a_1.conda - sha256: c2a9c65a245c7bcb8c17c94dd716dad2d42b7c98e0c17cc5553a5c60242c4dda - md5: 6283140d7b2b55b6b095af939b71b13f + size: 790176 + timestamp: 1754908768807 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda + sha256: a1c8cecdf9966921e13f0ae921309a1f415dfbd2b791f2117cf7e8f5e61a48b6 + md5: 210a85a1119f97ea7887188d176db135 depends: - __osx >=10.13 license: LGPL-2.1-only purls: [] - size: 669052 - timestamp: 1740128415026 -- conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-h135ad9c_1.conda - sha256: ea5ed2b362b6dbc4ba7188eb4eaf576146e3dfc6f4395e9f0db76ad77465f786 - md5: 21fc5dba2cbcd8e5e26ff976a312122c + size: 737846 + timestamp: 1754908900138 +- conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + sha256: 0dcdb1a5f01863ac4e8ba006a8b0dc1a02d2221ec3319b5915a1863254d7efa7 + md5: 64571d1dd6cdcfa25d0664a5950fdaa2 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: LGPL-2.1-only purls: [] - size: 638142 - timestamp: 1740128665984 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda - sha256: 98b399287e27768bf79d48faba8a99a2289748c65cd342ca21033fab1860d4a4 - md5: 9fa334557db9f63da6c9285fd2a48638 + size: 696926 + timestamp: 1754909290005 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda + sha256: cc9aba923eea0af8e30e0f94f2ad7156e2984d80d1e8e7fe6be5a1f257f0eb32 + md5: 8397539e3a0bbd1695584fb4f927485a depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 constrains: - jpeg <0.0.0a license: IJG AND BSD-3-Clause AND Zlib purls: [] - size: 628947 - timestamp: 1745268527144 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.0-h6e16a3a_0.conda - sha256: 9c0009389c1439ec96a08e3bf7731ac6f0eab794e0a133096556a9ae10be9c27 - md5: 87537967e6de2f885a9fcebd42b7cb10 + size: 633710 + timestamp: 1762094827865 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.2-h8616949_0.conda + sha256: ebe2877abc046688d6ea299e80d8322d10c69763f13a102010f90f7168cc5f54 + md5: 48dda187f169f5a8f1e5e07701d5cdd9 depends: - __osx >=10.13 constrains: - jpeg <0.0.0a license: IJG AND BSD-3-Clause AND Zlib purls: [] - size: 586456 - timestamp: 1745268522731 -- conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.0-h2466b09_0.conda - sha256: e61b0adef3028b51251124e43eb6edf724c67c0f6736f1628b02511480ac354e - md5: 7c51d27540389de84852daa1cdb9c63c + size: 586189 + timestamp: 1762095332781 +- conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda + sha256: 795e2d4feb2f7fc4a2c6e921871575feb32b8082b5760726791f080d1e2c2597 + md5: 56a686f92ac0273c0f6af58858a3f013 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - jpeg <0.0.0a license: IJG AND BSD-3-Clause AND Zlib purls: [] - size: 838154 - timestamp: 1745268437136 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-32_h7ac8fdf_openblas.conda - build_number: 32 - sha256: 5b55a30ed1b3f8195dad9020fe1c6d0f514829bfaaf0cf5e393e93682af009f2 - md5: 6c3f04ccb6c578138e9f9899da0bd714 + size: 841783 + timestamp: 1762094814336 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-38_h47877c9_openblas.conda + build_number: 38 + sha256: 63d6073dd4f82ab46943ad99a22fc4edda83b0f8fe6170bdaba7a43352bed007 + md5: 88f10bff57b423a3fd2d990c6055771e depends: - - libblas 3.9.0 32_h59b9bed_openblas + - libblas 3.9.0 38_h4a7cf45_openblas constrains: - - libcblas 3.9.0 32*_openblas - - blas 2.132 openblas - - liblapacke 3.9.0 32*_openblas + - libcblas 3.9.0 38*_openblas + - blas 2.138 openblas + - liblapacke 3.9.0 38*_openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17316 - timestamp: 1750388820745 -- conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-32_h236ab99_openblas.conda - build_number: 32 - sha256: 1e26450b80525b3f656e9c75fd26a10ebaa1d339fe4ca9c7affbebd9acbeac03 - md5: ccdca0c0730ad795e064d81dbe540723 + size: 17501 + timestamp: 1761680098660 +- conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-38_h859234e_openblas.conda + build_number: 38 + sha256: c94a3411dee3239702d632ff19f6b97b7aba5e51de3bc22caa229fb8d77d2978 + md5: 062a7bd94939084574e2d401f8e0840e depends: - - libblas 3.9.0 32_h7f60823_openblas + - libblas 3.9.0 38_he492b99_openblas constrains: - - blas 2.132 openblas - - liblapacke 3.9.0 32*_openblas - - libcblas 3.9.0 32*_openblas + - blas 2.138 openblas + - libcblas 3.9.0 38*_openblas + - liblapacke 3.9.0 38*_openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17553 - timestamp: 1750389051033 -- conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-32_h1aa476e_mkl.conda - build_number: 32 - sha256: 5629e592137114b24bfdea71e1c4b6bee11379631409ed91dfe2f83b32a8b298 - md5: 1652285573db93afc3ba9b3b9356e3d3 + size: 17674 + timestamp: 1761680534375 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-38_hf9ab0e9_mkl.conda + build_number: 38 + sha256: 3b8d2d800f48fb9045a976c5a10cefe742142df88decf5a5108fe6b7c8fb5b50 + md5: eb3167046ffba0ceb4a8824fb1b79a69 depends: - - libblas 3.9.0 32_h641d27c_mkl + - libblas 3.9.0 38_hf2e6a31_mkl constrains: - - libcblas 3.9.0 32*_mkl - - liblapacke 3.9.0 32*_mkl - - blas 2.132 mkl + - blas 2.138 mkl + - liblapacke 3.9.0 38*_mkl + - libcblas 3.9.0 38*_mkl license: BSD-3-Clause license_family: BSD purls: [] - size: 3735534 - timestamp: 1750389164366 + size: 79298 + timestamp: 1761680854566 - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 md5: 1a580f7796c7bf6393fddb8bbbde58dc @@ -5586,42 +5720,42 @@ packages: purls: [] size: 88657 timestamp: 1723861474602 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda - sha256: b0f2b3695b13a989f75d8fd7f4778e1c7aabe3b36db83f0fe80b2cd812c0e975 - md5: 19e57602824042dfd0446292ef90488b +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + sha256: a4a7dab8db4dc81c736e9a9b42bdfd97b087816e029e221380511960ac46c690 + md5: b499ce4b026493a13774bcf0f4c33849 depends: - __glibc >=2.17,<3.0.a0 - - c-ares >=1.32.3,<2.0a0 + - c-ares >=1.34.5,<2.0a0 - libev >=4.33,<4.34.0a0 - libev >=4.33,<5.0a0 - - libgcc >=13 - - libstdcxx >=13 + - libgcc >=14 + - libstdcxx >=14 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.3.2,<4.0a0 + - openssl >=3.5.2,<4.0a0 license: MIT license_family: MIT purls: [] - size: 647599 - timestamp: 1729571887612 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.64.0-hc7306c3_0.conda - sha256: 0dcfdcf3a445d2d7de4f3b186ab0a794dc872f4ea21622f9b997be72712c027f - md5: ab21007194b97beade22ceb7a3f6fee5 + size: 666600 + timestamp: 1756834976695 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda + sha256: c48d7e1cc927aef83ff9c48ae34dd1d7495c6ccc1edc4a3a6ba6aff1624be9ac + md5: e7630cef881b1174d40f3e69a883e55f depends: - __osx >=10.13 - - c-ares >=1.34.2,<2.0a0 - - libcxx >=17 + - c-ares >=1.34.5,<2.0a0 + - libcxx >=19 - libev >=4.33,<4.34.0a0 - libev >=4.33,<5.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.3.2,<4.0a0 + - openssl >=3.5.2,<4.0a0 license: MIT license_family: MIT purls: [] - size: 606663 - timestamp: 1729572019083 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_0.conda - sha256: 225f4cfdb06b3b73f870ad86f00f49a9ca0a8a2d2afe59440521fafe2b6c23d9 - md5: 323dc8f259224d13078aaf7ce96c3efe + size: 605680 + timestamp: 1756835898134 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_3.conda + sha256: 200899e5acc01fa29550d2782258d9cf33e55ce4cbce8faed9c6fe0b774852aa + md5: ac2e4832427d6b159576e8a68305c722 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 @@ -5632,33 +5766,33 @@ packages: license: BSD-3-Clause license_family: BSD purls: [] - size: 5916819 - timestamp: 1750379877844 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.30-openmp_hbf64a52_0.conda - sha256: 933eb95a778657649a66b0e3cf638d591283159954c5e92b3918d67347ed47a1 - md5: 29c54869a3c7d33b6a0add39c5a325fe + size: 5918287 + timestamp: 1761748180250 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.30-openmp_h6006d49_3.conda + sha256: 209812edd396e0f395bee0a5628a8b77501e6671795c081455c27049e9a1c96a + md5: e32aca8f732f7ea1ed876ffbec0d6347 depends: - __osx >=10.13 - - libgfortran 5.* - - libgfortran5 >=13.3.0 - - llvm-openmp >=18.1.8 + - libgfortran + - libgfortran5 >=14.3.0 + - llvm-openmp >=19.1.7 constrains: - openblas >=0.3.30,<0.3.31.0a0 license: BSD-3-Clause license_family: BSD purls: [] - size: 6179547 - timestamp: 1750380498501 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hd1b1c89_0.conda - sha256: b88de51fa55513483e7c80c43d38ddd3559f8d17921879e4c99909ba66e1c16b - md5: 4b25cd8720fd8d5319206e4f899f2707 + size: 6265963 + timestamp: 1761751583325 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda + sha256: ba9b09066f9abae9b4c98ffedef444bbbf4c068a094f6c77d70ef6f006574563 + md5: 1c0320794855f457dea27d35c4c71e23 depends: - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libcurl >=8.14.0,<9.0a0 - - libgrpc >=1.71.0,<1.72.0a0 - - libopentelemetry-cpp-headers 1.21.0 ha770c72_0 - - libprotobuf >=5.29.3,<5.29.4.0a0 + - libabseil >=20250512.1,<20250513.0a0 + - libcurl >=8.14.1,<9.0a0 + - libgrpc >=1.73.1,<1.74.0a0 + - libopentelemetry-cpp-headers 1.21.0 ha770c72_1 + - libprotobuf >=6.31.1,<6.31.2.0a0 - libzlib >=1.3.1,<2.0a0 - nlohmann_json - prometheus-cpp >=1.3.0,<1.4.0a0 @@ -5667,18 +5801,18 @@ packages: license: Apache-2.0 license_family: APACHE purls: [] - size: 882002 - timestamp: 1748592427188 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libopentelemetry-cpp-1.21.0-h30c661f_0.conda - sha256: 8cda74a4a2c835d8ef4aa38edfbe0a45e8969724b7f938d8a8148978c2e797c4 - md5: d6dbae8feabea4d090855e4ca85367aa + size: 885397 + timestamp: 1751782709380 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libopentelemetry-cpp-1.21.0-h7d3f41d_1.conda + sha256: 94df4129f94dbb17998a60bff0b53c700e6124a6cb67f3047fe7059ebaa7d357 + md5: 952dd64cff4a72cadf5e81572a7a81c8 depends: - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libcurl >=8.14.0,<9.0a0 - - libgrpc >=1.71.0,<1.72.0a0 - - libopentelemetry-cpp-headers 1.21.0 h694c41f_0 - - libprotobuf >=5.29.3,<5.29.4.0a0 + - libabseil >=20250512.1,<20250513.0a0 + - libcurl >=8.14.1,<9.0a0 + - libgrpc >=1.73.1,<1.74.0a0 + - libopentelemetry-cpp-headers 1.21.0 h694c41f_1 + - libprotobuf >=6.31.1,<6.31.2.0a0 - libzlib >=1.3.1,<2.0a0 - nlohmann_json - prometheus-cpp >=1.3.0,<1.4.0a0 @@ -5687,195 +5821,202 @@ packages: license: Apache-2.0 license_family: APACHE purls: [] - size: 581930 - timestamp: 1748592611479 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_0.conda - sha256: dbd811e7a7bd9b96fccffe795ba539ac6ffcc5e564d0bec607f62aa27fa86a17 - md5: 11b1bed92c943d3b741e8a1e1a815ed1 + size: 585875 + timestamp: 1751782877386 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_1.conda + sha256: b3a1b36d5f92fbbfd7b6426982a99561bdbd7e4adbafca1b7f127c9a5ab0a60f + md5: 9e298d76f543deb06eb0f3413675e13a license: Apache-2.0 license_family: APACHE purls: [] - size: 359509 - timestamp: 1748592389311 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libopentelemetry-cpp-headers-1.21.0-h694c41f_0.conda - sha256: 0e1e062cf75ea4ea898108e2bd1adac7cbf369d95584604bf3424ac8a600125b - md5: 55d26993919e0075f536dc3843b8d2a4 + size: 363444 + timestamp: 1751782679053 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libopentelemetry-cpp-headers-1.21.0-h694c41f_1.conda + sha256: 5b43ec55305a6fabd8eb37cee06bc3260d3641f260435194837d0b64faa0b355 + md5: 62636543478d53b28c1fc5efce346622 license: Apache-2.0 license_family: APACHE purls: [] - size: 360373 - timestamp: 1748592530474 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libparquet-20.0.0-h081d1f1_7_cpu.conda - build_number: 7 - sha256: 338aa913e5f68606baa86c5deebe4d4d1d615e0b3df40db200084837905201e2 - md5: f8714819f786deb7a10bd255d4e0740c + size: 362175 + timestamp: 1751782820895 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libparquet-22.0.0-h7376487_3_cpu.conda + build_number: 3 + sha256: 66ab48262ae7f6693bd55c33f615c8b44c8d69bf5512d415902da9bb2b852e8a + md5: bcf50f7920a7efac3e0ab38e83a18cde depends: - __glibc >=2.17,<3.0.a0 - - libarrow 20.0.0 h314c690_7_cpu - - libgcc >=13 - - libstdcxx >=13 - - libthrift >=0.21.0,<0.21.1.0a0 - - openssl >=3.5.0,<4.0a0 + - libarrow 22.0.0 h99e40f8_3_cpu + - libgcc >=14 + - libstdcxx >=14 + - libthrift >=0.22.0,<0.22.1.0a0 + - openssl >=3.5.4,<4.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 1243202 - timestamp: 1749948757263 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libparquet-20.0.0-h283e888_7_cpu.conda - build_number: 7 - sha256: 7f07b5471185916406a65ae68e0e9e979f6ed9c0fc5ee9481c21efeb767a1038 - md5: 277651d91dc62b011ed9505f2e092c72 + size: 1343082 + timestamp: 1761789715193 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libparquet-22.0.0-habb56ca_3_cpu.conda + build_number: 3 + sha256: 9d34ed36a238c3c6f31a5180dccc8f9bda7f672076905966d03b605b33364756 + md5: 19c7fb076f59a6ca56ffc397064986d9 depends: - - __osx >=10.14 - - libarrow 20.0.0 hd0d6b81_7_cpu - - libcxx >=18 - - libthrift >=0.21.0,<0.21.1.0a0 - - openssl >=3.5.0,<4.0a0 + - __osx >=11.0 + - libabseil * cxx17* + - libabseil >=20250512.1,<20250513.0a0 + - libarrow 22.0.0 hb95b15f_3_cpu + - libcxx >=19 + - libopentelemetry-cpp >=1.21.0,<1.22.0a0 + - libprotobuf >=6.31.1,<6.31.2.0a0 + - libthrift >=0.22.0,<0.22.1.0a0 + - openssl >=3.5.4,<4.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 965768 - timestamp: 1749947460760 -- conda: https://conda.anaconda.org/conda-forge/win-64/libparquet-20.0.0-ha850022_7_cpu.conda - build_number: 7 - sha256: f8af85e9c36a51f13691f8707c94bdb602c246ba29d2bb650acb975cf52d2b4f - md5: e93ecaad4ea95579ec489324897cc41b + size: 1074342 + timestamp: 1761790347922 +- conda: https://conda.anaconda.org/conda-forge/win-64/libparquet-22.0.0-h7051d1f_3_cpu.conda + build_number: 3 + sha256: 764ade8ecc8aac1cf8ba8cb48621cc338d7ee58a21303bb0c613d8562a33e2cb + md5: 1769e64f8b40f856ec7425334f994c00 depends: - - libarrow 20.0.0 hc090743_7_cpu - - libthrift >=0.21.0,<0.21.1.0a0 - - openssl >=3.5.0,<4.0a0 + - libarrow 22.0.0 h0832232_3_cpu + - libthrift >=0.22.0,<0.22.1.0a0 + - openssl >=3.5.4,<4.0a0 - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: APACHE purls: [] - size: 822306 - timestamp: 1749950719758 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.49-h943b412_0.conda - sha256: c8f5dc929ba5fcee525a66777498e03bbcbfefc05a0773e5163bb08ac5122f1a - md5: 37511c874cf3b8d0034c8d24e73c0884 + size: 920465 + timestamp: 1762051662607 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.50-h421ea60_1.conda + sha256: e75a2723000ce3a4b9fd9b9b9ce77553556c93e475a4657db6ed01abc02ea347 + md5: 7af8e91b0deb5f8e25d1a595dea79614 depends: + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - libzlib >=1.3.1,<2.0a0 license: zlib-acknowledgement purls: [] - size: 289506 - timestamp: 1750095629466 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.49-h3c4a55f_0.conda - sha256: 37be190992433d20336187b6fee4986cbdb11e9f901bc888aca5b2d7e5a2acc6 - md5: b9eabfc716af02b8d3ec5a51cb89b4a9 + size: 317390 + timestamp: 1753879899951 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.50-h84aeda2_1.conda + sha256: 8d92c82bcb09908008d8cf5fab75e20733810d40081261d57ef8cd6495fc08b4 + md5: 1fe32bb16991a24e112051cc0de89847 depends: - __osx >=10.13 - libzlib >=1.3.1,<2.0a0 license: zlib-acknowledgement purls: [] - size: 267502 - timestamp: 1750095826947 -- conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.49-h7a4582a_0.conda - sha256: 8876a2d32d3538675e035b6560691471a1571835c0bcbf23816c24c460d31439 - md5: 27269977c8f25d499727ceabc47cee3d + size: 297609 + timestamp: 1753879919854 +- conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.50-h7351971_1.conda + sha256: e84b041f91c94841cb9b97952ab7f058d001d4a15ed4ce226ec5fdb267cc0fa5 + md5: 3ae6e9f5c47c495ebeed95651518be61 depends: - - libzlib >=1.3.1,<2.0a0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.1,<2.0a0 license: zlib-acknowledgement purls: [] - size: 347727 - timestamp: 1750096091724 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.29.3-h501fc15_1.conda - sha256: 691af28446345674c6b3fb864d0e1a1574b6cc2f788e0f036d73a6b05dcf81cf - md5: edb86556cf4a0c133e7932a1597ff236 + size: 382709 + timestamp: 1753879944850 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_2.conda + sha256: 1679f16c593d769f3dab219adb1117cbaaddb019080c5a59f79393dc9f45b84f + md5: 94cb88daa0892171457d9fdc69f43eca depends: - __glibc >=2.17,<3.0.a0 - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libgcc >=13 - - libstdcxx >=13 + - libabseil >=20250512.1,<20250513.0a0 + - libgcc >=14 + - libstdcxx >=14 - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD purls: [] - size: 3358788 - timestamp: 1745159546868 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libprotobuf-5.29.3-h1c7185b_1.conda - sha256: cc4dd61aa257c4b4a9451ddf9a5148e4640fea0df416737c1086724ca09641f6 - md5: 7c7d8218221568e544986713881d36ee + size: 4645876 + timestamp: 1760550892361 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libprotobuf-6.31.1-h03562ea_2.conda + sha256: 40a32a77cdb7f7b49187a4c9faf5c7812d95233288ab96b06e0dd9978ecd8e6d + md5: 39b7711c03a0d0533e832e734641e56e depends: - - __osx >=10.14 + - __osx >=11.0 - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 - - libcxx >=18 + - libabseil >=20250512.1,<20250513.0a0 + - libcxx >=19 - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD purls: [] - size: 2840883 - timestamp: 1745159228883 -- conda: https://conda.anaconda.org/conda-forge/win-64/libprotobuf-5.29.3-he9d8c4a_1.conda - sha256: 101b6cd0bde3ea29a161c9d36beda20851c0426e115d845555222e75d620d33e - md5: d1d3b80a1a04251bd75439b630e874be + size: 3550823 + timestamp: 1760550860606 +- conda: https://conda.anaconda.org/conda-forge/win-64/libprotobuf-6.31.1-hdcda5b4_2.conda + sha256: bb28909aef3777c5e950b769b30fe4bf02e0a7fb5322e583042a5cdc76bb15d0 + md5: 0e44c704760bbe4b696d981c3313f665 depends: - libabseil * cxx17* - - libabseil >=20250127.1,<20250128.0a0 + - libabseil >=20250512.1,<20250513.0a0 - libzlib >=1.3.1,<2.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: BSD-3-Clause license_family: BSD purls: [] - size: 6898266 - timestamp: 1745160248538 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2024.07.02-hba17884_3.conda - sha256: 392ec1e49370eb03270ffd4cc8d727f8e03e1e3a92b12f10c53f396ae4554668 - md5: 545e93a513c10603327c76c15485e946 + size: 7787239 + timestamp: 1760550955606 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h7b12aa8_0.conda + sha256: eb5d5ef4d12cdf744e0f728b35bca910843c8cf1249f758cf15488ca04a21dbb + md5: a30848ebf39327ea078cf26d114cff53 depends: - __glibc >=2.17,<3.0.a0 - libabseil * cxx17* - - libabseil >=20250127.0,<20250128.0a0 - - libgcc >=13 - - libstdcxx >=13 + - libabseil >=20250512.1,<20250513.0a0 + - libgcc >=14 + - libstdcxx >=14 constrains: - - re2 2024.07.02.* + - re2 2025.11.05.* license: BSD-3-Clause license_family: BSD purls: [] - size: 210073 - timestamp: 1741121121238 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libre2-11-2024.07.02-h08ce7b7_3.conda - sha256: 2bdf91b94486a06bdcc2aedcae4f0b9280301b0bb39e3168e29767c0c7b8bd85 - md5: 93ff94e5535b7051133b980d2ab1c858 + size: 211099 + timestamp: 1762397758105 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libre2-11-2025.11.05-h554ac88_0.conda + sha256: 901fb4cfdabf1495e7f080f8e8e218d1ad182c9bcd3cea2862481fef0e9d534f + md5: a0237623ed85308cb816c3dcced23db2 depends: - - __osx >=10.14 + - __osx >=11.0 - libabseil * cxx17* - - libabseil >=20250127.0,<20250128.0a0 - - libcxx >=18 + - libabseil >=20250512.1,<20250513.0a0 + - libcxx >=19 constrains: - - re2 2024.07.02.* + - re2 2025.11.05.* license: BSD-3-Clause license_family: BSD purls: [] - size: 179620 - timestamp: 1741121212954 -- conda: https://conda.anaconda.org/conda-forge/win-64/libre2-11-2024.07.02-hd248061_3.conda - sha256: 1e037dc1bc0fdaced4e103280f30d6f272ca15558a33d9f770ba64172eb699e8 - md5: ba8d5530e951114fc3227780393d9ce2 + size: 180107 + timestamp: 1762398117273 +- conda: https://conda.anaconda.org/conda-forge/win-64/libre2-11-2025.11.05-h0eb2380_0.conda + sha256: 8eb2c205588e6d751fe387e90f1321ac8bbaef0a12d125a1dd898e925327f8ae + md5: 960713477ad3d7f82e5199fa1b940495 depends: - libabseil * cxx17* - - libabseil >=20250127.0,<20250128.0a0 + - libabseil >=20250512.1,<20250513.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - - re2 2024.07.02.* + - re2 2025.11.05.* license: BSD-3-Clause license_family: BSD purls: [] - size: 263495 - timestamp: 1741121665560 + size: 263996 + timestamp: 1762397947932 - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda sha256: 0105bd108f19ea8e6a78d2d994a6d4a8db16d19a41212070d2d1d48a63c34161 md5: a587892d3c13b6621a6091be690dbca2 @@ -5905,39 +6046,39 @@ packages: purls: [] size: 202344 timestamp: 1716828757533 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.1-h6cd9bfd_6.conda - sha256: 0ef71429958415129e6ae1d675006e2a6c13346d1c757665db780e4e7413d7ae - md5: a5ea64ea2bd58803ea85e3769a659829 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda + sha256: 4c992dcd0e34b68f843e75406f7f303b1b97c248d18f3c7c330bdc0bc26ae0b3 + md5: 729a572a3ebb8c43933b30edcc628ceb depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - icu >=75.1,<76.0a0 + - libgcc >=14 - libzlib >=1.3.1,<2.0a0 - license: Unlicense + license: blessing purls: [] - size: 919463 - timestamp: 1750689098065 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.50.1-h7cec44d_6.conda - sha256: a2bb0450dff0de87be6871e444b203389b7aed9a9a1bfb4652d25acec49bcb12 - md5: f8032fecb583392b6fe01873f2bcabde + size: 945576 + timestamp: 1762299687230 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.0-h86bffb9_0.conda + sha256: ad151af8192c17591fad0b68c9ffb7849ad9f4be9da2020b38b8befd2c5f6f02 + md5: 1ee9b74571acd6dd87e6a0f783989426 depends: - __osx >=10.13 - - icu >=75.1,<76.0a0 - libzlib >=1.3.1,<2.0a0 - license: Unlicense + license: blessing purls: [] - size: 984463 - timestamp: 1750689233934 -- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.50.1-hf5d6505_6.conda - sha256: 56b8ba674b8dec6d169ee39434e68c8654e4327fd5705594fcc19625660630ad - md5: c01fd2d0873bdc8d35bfa3c6eb2f54e5 + size: 986898 + timestamp: 1762300146976 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.0-hf5d6505_0.conda + sha256: 2373bd7450693bd0f624966e1bee2f49b0bf0ffbc114275ed0a43cf35aec5b21 + md5: d2c9300ebd2848862929b18c264d1b1e depends: - ucrt >=10.0.20348.0 - vc >=14.3,<15 - vc14_runtime >=14.44.35208 - license: Unlicense + license: blessing purls: [] - size: 1291823 - timestamp: 1750689395515 + size: 1292710 + timestamp: 1762299749044 - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda sha256: fa39bfd69228a13e553bd24601332b7cfeb30ca11a3ca50bb028108fe90a7661 md5: eecce068c7e4eddeb169591baac20ac4 @@ -5977,229 +6118,232 @@ packages: purls: [] size: 292785 timestamp: 1745608759342 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda - sha256: 6ae3d153e78f6069d503d9309f2cac6de5b93d067fc6433160a4c05226a5dad4 - md5: 1cb1c67961f6dd257eae9e9691b341aa +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda + sha256: 1b981647d9775e1cdeb2fab0a4dd9cd75a6b0de2963f6c3953dbd712f78334b3 + md5: 5b767048b1b3ee9a954b06f4084f93dc depends: - __glibc >=2.17,<3.0.a0 - - libgcc 15.1.0 h767d61c_2 + - libgcc 15.2.0 h767d61c_7 + constrains: + - libstdcxx-ng ==15.2.0=*_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 3902355 - timestamp: 1746642227493 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_2.conda - sha256: 11bea86e11de7d6bce87589197a383344df3fa0a3552dab7e931785ff1159a5b - md5: 9d2072af184b5caa29492bf2344597bb + size: 3898269 + timestamp: 1759968103436 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda + sha256: 024fd46ac3ea8032a5ec3ea7b91c4c235701a8bf0e6520fe5e6539992a6bd05f + md5: f627678cf829bd70bccf141a19c3ad3e depends: - - libstdcxx 15.1.0 h8f9b012_2 + - libstdcxx 15.2.0 h8f9b012_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 34647 - timestamp: 1746642266826 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.21.0-h0e7cc3e_0.conda - sha256: ebb395232973c18745b86c9a399a4725b2c39293c9a91b8e59251be013db42f0 - md5: dcb95c0a98ba9ff737f7ae482aef7833 + size: 29343 + timestamp: 1759968157195 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda + sha256: 4888b9ea2593c36ca587a5ebe38d0a56a0e6d6a9e4bb7da7d9a326aaaca7c336 + md5: 8ed82d90e6b1686f5e98f8b7825a15ef depends: - __glibc >=2.17,<3.0.a0 - libevent >=2.1.12,<2.1.13.0a0 - - libgcc >=13 - - libstdcxx >=13 + - libgcc >=14 + - libstdcxx >=14 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.3.2,<4.0a0 + - openssl >=3.5.1,<4.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 425773 - timestamp: 1727205853307 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libthrift-0.21.0-h75589b3_0.conda - sha256: 3f82eddd6de435a408538ac81a7a2c0c155877534761ec9cd7a2906c005cece2 - md5: 7a472cd20d9ae866aeb6e292b33381d6 + size: 424208 + timestamp: 1753277183984 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libthrift-0.22.0-h687e942_1.conda + sha256: a0f9fdc663db089fde4136a0bd6c819d7f8daf869fc3ca8582201412e47f298c + md5: 69251ed374b31a5664bf5ba58626f3b7 depends: - __osx >=10.13 - - libcxx >=17 + - libcxx >=19 - libevent >=2.1.12,<2.1.13.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.3.2,<4.0a0 + - openssl >=3.5.1,<4.0a0 license: Apache-2.0 license_family: APACHE purls: [] - size: 332651 - timestamp: 1727206546431 -- conda: https://conda.anaconda.org/conda-forge/win-64/libthrift-0.21.0-hbe90ef8_0.conda - sha256: 81ca4873ba09055c307f8777fb7d967b5c26291f38095785ae52caed75946488 - md5: 7699570e1f97de7001a7107aabf2d677 + size: 331822 + timestamp: 1753277335578 +- conda: https://conda.anaconda.org/conda-forge/win-64/libthrift-0.22.0-h23985f6_1.conda + sha256: 87516b128ffa497fc607d5da0cc0366dbee1dbcc14c962bf9ea951d480c7698b + md5: 556d49ad5c2ad553c2844cc570bb71c7 depends: - libevent >=2.1.12,<2.1.13.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.3.2,<4.0a0 + - openssl >=3.5.1,<4.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: APACHE purls: [] - size: 633857 - timestamp: 1727206429954 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda - sha256: 7fa6ddac72e0d803bb08e55090a8f2e71769f1eb7adbd5711bdd7789561601b1 - md5: e79a094918988bb1807462cd42c83962 + size: 636513 + timestamp: 1753277481158 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda + sha256: e5f8c38625aa6d567809733ae04bb71c161a42e44a9fa8227abe61fa5c60ebe0 + md5: cd5a90476766d53e901500df9215e927 depends: - __glibc >=2.17,<3.0.a0 - lerc >=4.0.0,<5.0a0 - - libdeflate >=1.24,<1.25.0a0 - - libgcc >=13 + - libdeflate >=1.25,<1.26.0a0 + - libgcc >=14 - libjpeg-turbo >=3.1.0,<4.0a0 - liblzma >=5.8.1,<6.0a0 - - libstdcxx >=13 - - libwebp-base >=1.5.0,<2.0a0 + - libstdcxx >=14 + - libwebp-base >=1.6.0,<2.0a0 - libzlib >=1.3.1,<2.0a0 - zstd >=1.5.7,<1.6.0a0 license: HPND purls: [] - size: 429575 - timestamp: 1747067001268 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.0-h1167cee_5.conda - sha256: 517a34be9fc697aaf930218f6727a2eff7c38ee57b3b41fd7d1cc0d72aaac562 - md5: fc84af14a09e779f1d37ab1d16d5c4e2 + size: 435273 + timestamp: 1762022005702 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda + sha256: e53424c34147301beae2cd9223ebf593720d94c038b3f03cacd0535e12c9668e + md5: 9d4344f94de4ab1330cdc41c40152ea6 depends: - __osx >=10.13 - lerc >=4.0.0,<5.0a0 - - libcxx >=18 - - libdeflate >=1.24,<1.25.0a0 + - libcxx >=19 + - libdeflate >=1.25,<1.26.0a0 - libjpeg-turbo >=3.1.0,<4.0a0 - liblzma >=5.8.1,<6.0a0 - - libwebp-base >=1.5.0,<2.0a0 + - libwebp-base >=1.6.0,<2.0a0 - libzlib >=1.3.1,<2.0a0 - zstd >=1.5.7,<1.6.0a0 license: HPND purls: [] - size: 400062 - timestamp: 1747067122967 -- conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h05922d8_5.conda - sha256: 1bb0b2e7d076fecc2f8147336bc22e7e6f9a4e0505e0e4ab2be1f56023a4a458 - md5: 75370aba951b47ec3b5bfe689f1bcf7f + size: 404591 + timestamp: 1762022511178 +- conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda + sha256: f1b8cccaaeea38a28b9cd496694b2e3d372bb5be0e9377c9e3d14b330d1cba8a + md5: 549845d5133100142452812feb9ba2e8 depends: - lerc >=4.0.0,<5.0a0 - - libdeflate >=1.24,<1.25.0a0 + - libdeflate >=1.25,<1.26.0a0 - libjpeg-turbo >=3.1.0,<4.0a0 - liblzma >=5.8.1,<6.0a0 - libzlib >=1.3.1,<2.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - zstd >=1.5.7,<1.6.0a0 license: HPND purls: [] - size: 979074 - timestamp: 1747067408877 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.10.0-h202a827_0.conda - sha256: c4ca78341abb308134e605476d170d6f00deba1ec71b0b760326f36778972c0e - md5: 0f98f3e95272d118f7931b6bef69bfe5 + size: 993166 + timestamp: 1762022118895 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.0-hb04c3b8_0.conda + sha256: f8977233dc19cb8530f3bc71db87124695db076e077db429c3231acfa980c4ac + md5: 34fb73fd2d5a613d8f17ce2eaa15a8a5 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 83080 - timestamp: 1748341697686 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libutf8proc-2.10.0-h5b79583_0.conda - sha256: da7f0f9efd5f41cebf53a08fe80c573aeed835b26dabf48c9e3fe0401940becb - md5: 9959d0d69e3b42a127e3c9d32f21ca16 + size: 85741 + timestamp: 1757742873826 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libutf8proc-2.11.0-h64b4c5c_0.conda + sha256: e6f51b766003b8b17de2f58748ab861b7926530ada2ad5240f036765cbc99f49 + md5: 71bcdd36cc29097151a0ad8e5fecb537 depends: - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 80819 - timestamp: 1748341791870 -- conda: https://conda.anaconda.org/conda-forge/win-64/libutf8proc-2.10.0-hff4702e_0.conda - sha256: c3588c52e50666d631e21fffdc057594dbb78464bb87b5832fee3f713a1e4c52 - md5: 0c661f61710bf7fec2ea584d276208d7 + size: 84601 + timestamp: 1757743187278 +- conda: https://conda.anaconda.org/conda-forge/win-64/libutf8proc-2.11.0-h0b34c2f_0.conda + sha256: 3f006d2736a1d9ba7c195f39674c098753b19f6d05458ec5dc0333ded634d3a2 + md5: 0abd9826c6444cea1313424d9046c0c8 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: [] - size: 85704 - timestamp: 1748342286008 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - sha256: 787eb542f055a2b3de553614b25f09eefb0a0931b0c87dbcce6efdfd92f04f18 - md5: 40b61aab5c7ba9ff276c41cfffe6b80b + size: 89218 + timestamp: 1757743049736 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda + sha256: e5ec6d2ad7eef538ddcb9ea62ad4346fde70a4736342c4ad87bd713641eb9808 + md5: 80c07c68d2f6870250959dcc95b209d1 depends: - - libgcc-ng >=12 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 license: BSD-3-Clause license_family: BSD purls: [] - size: 33601 - timestamp: 1680112270483 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb9d3cd8_0.conda - sha256: 770ca175d64323976c9fe4303042126b2b01c1bd54c8c96cafeaba81bdb481b8 - md5: 1349c022c92c5efd3fd705a79a5804d8 + size: 37135 + timestamp: 1758626800002 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + sha256: c180f4124a889ac343fc59d15558e93667d894a966ec6fdb61da1604481be26b + md5: 0f03292cc56bf91a077a134ea8747118 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 890145 - timestamp: 1748304699136 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h4cb831e_0.conda - sha256: 2c820c8e26d680f74035f58c3d46593461bb8aeefa00faafa5ca39d8a51c87fa - md5: 8afd5432c2e6776d145d94f4ea4d4db5 + size: 895108 + timestamp: 1753948278280 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda + sha256: d90dd0eee6f195a5bd14edab4c5b33be3635b674b0b6c010fb942b956aa2254c + md5: fbfc6cf607ae1e1e498734e256561dc3 depends: - - __osx >=11.0 + - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 420355 - timestamp: 1748304826637 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda - sha256: c45283fd3e90df5f0bd3dbcd31f59cdd2b001d424cf30a07223655413b158eaf - md5: 63f790534398730f59e1b899c3644d4a + size: 422612 + timestamp: 1753948458902 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda + sha256: 3aed21ab28eddffdaf7f804f49be7a7d701e8f0e46c856d801270b470820a37b + md5: aea31d2e5b1091feca96fcfe945c3cf9 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 constrains: - - libwebp 1.5.0 + - libwebp 1.6.0 license: BSD-3-Clause license_family: BSD purls: [] - size: 429973 - timestamp: 1734777489810 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.5.0-h6cf52b4_0.conda - sha256: 7f110eba04150f1fe5fe297f08fb5b82463eed74d1f068bc67c96637f9c63569 - md5: 5e0cefc99a231ac46ba21e27ae44689f + size: 429011 + timestamp: 1752159441324 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda + sha256: 00dbfe574b5d9b9b2b519acb07545380a6bc98d1f76a02695be4995d4ec91391 + md5: 7bb6608cf1f83578587297a158a6630b depends: - __osx >=10.13 constrains: - - libwebp 1.5.0 + - libwebp 1.6.0 license: BSD-3-Clause license_family: BSD purls: [] - size: 357662 - timestamp: 1734777539822 -- conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.5.0-h3b0e114_0.conda - sha256: 1d75274614e83a5750b8b94f7bad2fc0564c2312ff407e697d99152ed095576f - md5: 33f7313967072c6e6d8f865f5493c7ae + size: 365086 + timestamp: 1752159528504 +- conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda + sha256: 7b6316abfea1007e100922760e9b8c820d6fc19df3f42fb5aca684cfacb31843 + md5: f9bbae5e2537e3b06e0f7310ba76c893 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - - libwebp 1.5.0 + - libwebp 1.6.0 license: BSD-3-Clause license_family: BSD purls: [] - size: 273661 - timestamp: 1734777665516 -- conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda - sha256: 373f2973b8a358528b22be5e8d84322c165b4c5577d24d94fd67ad1bb0a0f261 - md5: 08bfa5da6e242025304b206d152479ef + size: 279176 + timestamp: 1752159543911 +- conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda + sha256: 0fccf2d17026255b6e10ace1f191d0a2a18f2d65088fd02430be17c701f8ffe0 + md5: 8a86073cf3b343b87d03f41790d8b4e5 depends: - ucrt constrains: @@ -6207,8 +6351,8 @@ packages: - msys2-conda-epoch <0.0a0 license: MIT AND BSD-3-Clause-Clear purls: [] - size: 35794 - timestamp: 1737099561703 + size: 36621 + timestamp: 1759768399557 - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda sha256: 666c0c431b23c6cec6e492840b176dde533d48b7e6fb8883f5071223433776aa md5: 92ed62436b625154323d40d5f2f11dd7 @@ -6251,49 +6395,107 @@ packages: purls: [] size: 1208687 timestamp: 1727279378819 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda - sha256: b0b3a96791fa8bb4ec030295e8c8bf2d3278f33c0f9ad540e73b5e538e6268e7 - md5: 14dbe05b929e329dbaa6f2d0aa19466d +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda + sha256: ec0735ae56c3549149eebd7dc22c0bed91fd50c02eaa77ff418613ddda190aa8 + md5: e512be7dc1f84966d50959e900ca121f depends: - __glibc >=2.17,<3.0.a0 - icu >=75.1,<76.0a0 - - libgcc >=13 + - libgcc >=14 - libiconv >=1.18,<2.0a0 - liblzma >=5.8.1,<6.0a0 + - libxml2-16 2.15.1 ha9997c6_0 - libzlib >=1.3.1,<2.0a0 license: MIT license_family: MIT purls: [] - size: 690864 - timestamp: 1746634244154 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.13.8-h93c44a6_0.conda - sha256: 4b29663164d7beb9a9066ddcb8578fc67fe0e9b40f7553ea6255cd6619d24205 - md5: e42a93a31cbc6826620144343d42f472 + size: 45283 + timestamp: 1761015644057 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h23bb396_0.conda + sha256: a40ec252d9c50fee7cb0b15be7e358a10888c89dadb23deac254789fcb047de7 + md5: 65dd26de1eea407dda59f0da170aed22 depends: - __osx >=10.13 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2-16 2.15.1 h0ad03eb_0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - icu <0.0a0 + license: MIT + license_family: MIT + purls: [] + size: 40433 + timestamp: 1761016207984 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.1-h5d26750_0.conda + sha256: f507960adf64ee9c9c7b7833d8b11980765ebd2bf5345f73d5a3b21b259eaed5 + md5: 9176ee05643a1bfe7f2e7b4c921d2c3d + depends: + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2-16 2.15.1 h692994f_0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - icu <0.0a0 + license: MIT + license_family: MIT + purls: [] + size: 43209 + timestamp: 1761016354235 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda + sha256: 71436e72a286ef8b57d6f4287626ff91991eb03c7bdbe835280521791efd1434 + md5: e7733bc6785ec009e47a224a71917e84 + depends: + - __glibc >=2.17,<3.0.a0 - icu >=75.1,<76.0a0 + - libgcc >=14 - libiconv >=1.18,<2.0a0 - liblzma >=5.8.1,<6.0a0 - libzlib >=1.3.1,<2.0a0 + constrains: + - libxml2 2.15.1 + license: MIT + license_family: MIT + purls: [] + size: 556302 + timestamp: 1761015637262 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-h0ad03eb_0.conda + sha256: 00ddbcfbd0318f3c5dbf2b1e1bc595915efe2a61e73b844df422b11fec39d7d8 + md5: 8487998051f3d300fef701a49c27f282 + depends: + - __osx >=10.13 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - icu <0.0a0 + - libxml2 2.15.1 license: MIT license_family: MIT purls: [] - size: 609197 - timestamp: 1746634704204 -- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.8-h442d1da_0.conda - sha256: 473b8a53c8df714d676ab41711551c8d250f8d799f2db5cb7cb2b177a0ce13f6 - md5: 833c2dbc1a5020007b520b044c713ed3 + size: 493432 + timestamp: 1761016183078 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h692994f_0.conda + sha256: 04129dc2df47a01c55e5ccf8a18caefab94caddec41b3b10fbc409e980239eb9 + md5: 70ca4626111579c3cd63a7108fe737f9 depends: - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 - libzlib >=1.3.1,<2.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - icu <0.0a0 + - libxml2 2.15.1 license: MIT license_family: MIT purls: [] - size: 1513627 - timestamp: 1746634633560 + size: 518135 + timestamp: 1761016320405 - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 md5: edb0dca6bc32e4f4789199455a1dbeb8 @@ -6345,18 +6547,34 @@ packages: - pkg:pypi/linkify-it-py?source=hash-mapping size: 24154 timestamp: 1733781296133 -- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.7-ha54dae1_0.conda - sha256: 18d3b64965c1f5f7cd24a140b3e4f49191dd579cc8ca6d3db220830caf8aae3d - md5: e240159643214102dc88395c4ecee9cf +- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-21.1.5-h472b3d1_0.conda + sha256: 1139bbc6465515e328f63f6c3ef4c045c3159b8aa5b23050f4360c6f7e128805 + md5: 5e486397a9547fbf4e454450389f7f18 depends: - __osx >=10.13 constrains: - - openmp 20.1.7|20.1.7.* + - intel-openmp <0.0a0 + - openmp 21.1.5|21.1.5.* license: Apache-2.0 WITH LLVM-exception license_family: APACHE purls: [] - size: 306443 - timestamp: 1749892271445 + size: 310792 + timestamp: 1762315894069 +- conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-21.1.5-hfa2b4ca_0.conda + sha256: 8c5106720e5414f48344fd28eae4db4f1a382336d8a0f30f71d41d8ae730fbb6 + md5: 3bd3154b24a1b9489d4ab04d62ffcc86 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - openmp 21.1.5|21.1.5.* + - intel-openmp <0.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + purls: [] + size: 347688 + timestamp: 1762315988146 - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 sha256: 9afe0b5cfa418e8bdb30d8917c5a6cec10372b037924916f1f85b9f4899a67a6 md5: 91e27ef3d05cc772ce627e51cff111c4 @@ -6368,51 +6586,57 @@ packages: - pkg:pypi/locket?source=hash-mapping size: 8250 timestamp: 1650660473123 -- conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-4.4.4-py313h8756d67_0.conda - sha256: 0dda09a39f20464fc8115c65574a3223be10ccd214b35f0cd083aa56253940b8 - md5: c56653951f28dcd2c5be9338208b23df +- conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-4.4.5-py313h28739b2_0.conda + sha256: 60df6034941808d80b6a3639225659743d91e567e12e796eedb7cb27de725197 + md5: 991ea3cc00eab4e898759c06d51d4ed8 depends: + - python + - lz4-c + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - lz4-c >=1.10.0,<1.11.0a0 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 + - lz4-c >=1.10.0,<1.11.0a0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/lz4?source=hash-mapping - size: 40468 - timestamp: 1746562034878 -- conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-4.4.4-py313hc9bb01a_0.conda - sha256: 9b1f6047b5403037b9d31ec9e57d14146112fdaa152bdd9b20488d9be9f8ae22 - md5: 4433183e63ba82036f89765f28ef3883 + size: 44915 + timestamp: 1762351349252 +- conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-4.4.5-py313hab77a93_0.conda + sha256: eb369199113c24919349baefc8913f5ac981a3451f7731d31c3a47572e86cd4d + md5: 300e9a54fd2b2766c24b0efdc4cf19db depends: + - python + - lz4-c - __osx >=10.13 - lz4-c >=1.10.0,<1.11.0a0 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/lz4?source=hash-mapping - size: 38016 - timestamp: 1746562174504 -- conda: https://conda.anaconda.org/conda-forge/win-64/lz4-4.4.4-py313h05901a4_0.conda - sha256: 8487c2c4da6c8efb33ddd0433d31ff1bb3d0217f835260d104a0ebaad614f595 - md5: 69b4bcd6174e17d2350a8232cd97db02 + size: 42535 + timestamp: 1762351337269 +- conda: https://conda.anaconda.org/conda-forge/win-64/lz4-4.4.5-py313h4bbca4b_0.conda + sha256: 9d0194f4fb4659fca1bd5c0c55eae3a46cb122e8945db6368906e452cfa9345e + md5: f2a9cabf1944982c912a2341c2de04e8 depends: - - lz4-c >=1.10.0,<1.11.0a0 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python + - lz4-c + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + - lz4-c >=1.10.0,<1.11.0a0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/lz4?source=hash-mapping - size: 43362 - timestamp: 1746562513761 + size: 46581 + timestamp: 1762351307915 - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda sha256: 47326f811392a5fd3055f0f773036c392d26fdb32e4d8e7a8197eed951489346 md5: 9de5350a85c4a20c685259b889aa6393 @@ -6448,36 +6672,36 @@ packages: purls: [] size: 139891 timestamp: 1733741168264 -- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.8.2-pyhd8ed1ab_0.conda - sha256: d495279d947e01300bfbc124859151be4eec3a088c1afe173323fd3aa89423b2 - md5: b0404922d0459f188768d1e613ed8a87 +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10-pyhcf101f3_1.conda + sha256: 32af5d32e3193b7c0ea02c33cc8753bfc0965d07e1aa58418a851d0bb94a7792 + md5: 934afb77580165027b869d4104ee002f depends: - importlib-metadata >=4.4 - - python >=3.9 + - python >=3.10 + - python license: BSD-3-Clause - license_family: BSD purls: - pkg:pypi/markdown?source=hash-mapping - size: 80353 - timestamp: 1750360406187 -- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - sha256: 0fbacdfb31e55964152b24d5567e9a9996e1e7902fb08eb7d91b5fd6ce60803a - md5: fee3164ac23dfca50cfcc8b85ddefb81 + size: 85401 + timestamp: 1762856570927 +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda + sha256: 7b1da4b5c40385791dbc3cc85ceea9fad5da680a27d5d3cb8bfaa185e304a89e + md5: 5b5203189eb668f042ac2b0826244964 depends: - mdurl >=0.1,<1 - - python >=3.9 + - python >=3.10 license: MIT license_family: MIT purls: - pkg:pypi/markdown-it-py?source=hash-mapping - size: 64430 - timestamp: 1733250550053 -- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py313h8060acc_1.conda - sha256: d812caf52efcea7c9fd0eafb21d45dadfd0516812f667b928bee50e87634fae5 - md5: 21b62c55924f01b6eef6827167b46acb + size: 64736 + timestamp: 1754951288511 +- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda + sha256: a530a411bdaaf0b1e4de8869dfaca46cb07407bc7dc0702a9e231b0e5ce7ca85 + md5: c14389156310b8ed3520d84f854be1ee depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 constrains: @@ -6486,11 +6710,11 @@ packages: license_family: BSD purls: - pkg:pypi/markupsafe?source=hash-mapping - size: 24856 - timestamp: 1733219782830 -- conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.2-py313h717bdf5_1.conda - sha256: 297242943522a907c270bc2f191d16142707d970541b9a093640801b767d7aa7 - md5: a6fbde71416d6eb9898fcabf505a85c5 + size: 25909 + timestamp: 1759055357045 +- conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.3-py313h0f4d31d_0.conda + sha256: 9c698da56e3bdae80be2a7bc0d19565971b36060155374d16fce14271c8b695c + md5: 884a82dc80ecd251e38d647808c424b3 depends: - __osx >=10.13 - python >=3.13,<3.14.0a0 @@ -6501,49 +6725,49 @@ packages: license_family: BSD purls: - pkg:pypi/markupsafe?source=hash-mapping - size: 24363 - timestamp: 1733219815199 -- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.2-py313hb4c8b1a_1.conda - sha256: f16cb398915f52d582bcea69a16cf69a56dab6ea2fab6f069da9c2c10f09534c - md5: ec9ecf6ee4cceb73a0c9a8cdfdf58bed + size: 25105 + timestamp: 1759055575973 +- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_0.conda + sha256: 988d14095c1392e055fd75e24544da2db01ade73b0c2f99ddc8e2b8678ead4cc + md5: 47eaaa4405741beb171ea6edc6eaf874 depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - jinja2 >=3.0.0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/markupsafe?source=hash-mapping - size: 27930 - timestamp: 1733220059655 -- conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda - sha256: 69b7dc7131703d3d60da9b0faa6dd8acbf6f6c396224cf6aef3e855b8c0c41c6 - md5: af6ab708897df59bd6e7283ceab1b56b + size: 28959 + timestamp: 1759055685616 +- conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + sha256: 9d690334de0cd1d22c51bc28420663f4277cfa60d34fa5cad1ce284a13f1d603 + md5: 00e120ce3e40bad7bfc78861ce3c4a25 depends: - - python >=3.9 + - python >=3.10 - traitlets license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/matplotlib-inline?source=hash-mapping - size: 14467 - timestamp: 1733417051523 -- conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.4.2-pyhd8ed1ab_1.conda - sha256: c63ed79d9745109c0a70397713b0c07f06e7d3561abcb122cfc80a141ab3b449 - md5: af2060041d4f3250a7eb6ab3ec0e549b + - pkg:pypi/matplotlib-inline?source=compressed-mapping + size: 15175 + timestamp: 1761214578417 +- conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda + sha256: 123cc004e2946879708cdb6a9eff24acbbb054990d6131bb94bca7a374ebebfc + md5: 1997a083ef0b4c9331f9191564be275e depends: - - markdown-it-py >=1.0.0,<4.0.0 - - python >=3.9 + - markdown-it-py >=2.0.0,<5.0.0 + - python >=3.10 license: MIT license_family: MIT purls: - pkg:pypi/mdit-py-plugins?source=hash-mapping - size: 42180 - timestamp: 1733854816517 + size: 43805 + timestamp: 1754946862113 - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda sha256: 78c1bbe1723449c52b7a9df1af2ee5f005209f67e40b6e1d3c7619127c43b1c7 md5: 592132998493b3ff25fd7479396e8351 @@ -6566,19 +6790,19 @@ packages: - pkg:pypi/mergedeep?source=hash-mapping size: 11676 timestamp: 1734157119152 -- conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.3-pyh29332c3_0.conda - sha256: a67484d7dd11e815a81786580f18b6e4aa2392f292f29183631a6eccc8dc37b3 - md5: 7ec6576e328bc128f4982cd646eeba85 +- conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda + sha256: 609ea628ace5c6cdbdce772704e6cb159ead26969bb2f386ca1757632b0f74c6 + md5: f5a4d548d1d3bdd517260409fc21e205 depends: - - python >=3.9 + - python >=3.10 - typing_extensions - python license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/mistune?source=hash-mapping - size: 72749 - timestamp: 1742402716323 + size: 72996 + timestamp: 1756495311698 - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-1.6.1-pyhd8ed1ab_1.conda sha256: 902d2e251f9a7ffa7d86a3e62be5b2395e28614bd4dbe5f50acf921fd64a8c35 md5: 14661160be39d78f2b210f2cc2766059 @@ -6606,20 +6830,20 @@ packages: - pkg:pypi/mkdocs?source=hash-mapping size: 3524754 timestamp: 1734344673481 -- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-autorefs-1.4.2-pyhd8ed1ab_0.conda - sha256: ed8d25452bd4211a719183c73ef970a54f239d8224125937294396c09fad48ea - md5: d4468440b32d63e082e0d6c335b19a70 +- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-autorefs-1.4.3-pyhd8ed1ab_0.conda + sha256: 1631568d0d36bc182ec20c5b4c58cc053cdd77698b4741977776f592996d345b + md5: 1c024504ac97f1199023327a69066a8f depends: - markdown >=3.3 - markupsafe >=2.0.1 - mkdocs >=1.1 - pymdown-extensions - - python >=3.9 + - python >=3.10 license: ISC purls: - pkg:pypi/mkdocs-autorefs?source=hash-mapping - size: 34912 - timestamp: 1747758093008 + size: 35016 + timestamp: 1756236211878 - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-get-deps-0.2.0-pyhd8ed1ab_1.conda sha256: e0b501b96f7e393757fb2a61d042015966f6c5e9ac825925e43f9a6eafa907b6 md5: 84382acddb26c27c70f2de8d4c830830 @@ -6652,28 +6876,28 @@ packages: - pkg:pypi/mkdocs-jupyter?source=hash-mapping size: 1193541 timestamp: 1736802171415 -- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-9.6.14-pyhd8ed1ab_0.conda - sha256: 3e07277687f69476e1a94c361e07bcd3e9584e6364be4db1d03445e12f01fcae - md5: 85d4435caf917482a0005d143c4a6d31 +- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-9.7.0-pyhcf101f3_0.conda + sha256: c14cfff88be4ea779071f1ddb9c1944fa7d2a2c7f9ea09b8e0b9f5b84a70e6c1 + md5: 0ee60d02b6ffe184d355e1318d7e9207 depends: - - babel >=2.10,<3.dev0 - - backrefs >=5.7.post1,<6.dev0 - - colorama >=0.4,<1.dev0 + - python >=3.10 - jinja2 >=3.0,<4.dev0 - markdown >=3.2,<4.dev0 - mkdocs >=1.6,<2.dev0 - mkdocs-material-extensions >=1.3,<2.dev0 - - paginate >=0.5,<1.dev0 - pygments >=2.16,<3.dev0 - pymdown-extensions >=10.2,<11.dev0 - - python >=3.9 + - babel >=2.10,<3.dev0 + - colorama >=0.4,<1.dev0 + - paginate >=0.5,<1.dev0 + - backrefs >=5.7.post1,<6.dev0 - requests >=2.26,<3.dev0 + - python license: MIT - license_family: MIT purls: - pkg:pypi/mkdocs-material?source=hash-mapping - size: 4922259 - timestamp: 1747168634333 + size: 4793171 + timestamp: 1762865411798 - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-extensions-1.3.1-pyhd8ed1ab_1.conda sha256: f62955d40926770ab65cc54f7db5fde6c073a3ba36a0787a7a5767017da50aa3 md5: de8af4000a4872e16fb784c649679c8e @@ -6687,10 +6911,10 @@ packages: - pkg:pypi/mkdocs-material-extensions?source=hash-mapping size: 16122 timestamp: 1734641109286 -- pypi: https://files.pythonhosted.org/packages/24/ce/c8a41cb0f3044990c8afbdc20c853845a9e940995d4e0cffecafbb5e927b/mkdocs_mermaid2_plugin-1.2.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl name: mkdocs-mermaid2-plugin - version: 1.2.1 - sha256: 22d2cf2c6867d4959a5e0903da2dde78d74581fc0b107b791bc4c7ceb9ce9741 + version: 1.2.3 + sha256: 33f60c582be623ed53829a96e19284fc7f1b74a1dbae78d4d2e47fe00c3e190d requires_dist: - beautifulsoup4>=4.6.3 - jsbeautifier @@ -6703,9 +6927,9 @@ packages: - packaging ; extra == 'test' - requests-html ; extra == 'test' requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.29.1-pyhd8ed1ab_0.conda - sha256: 95399acb1d0d6bb501cc453d1672d1f52b9d44cdfd35f99d5126c57141d1fc18 - md5: 557c801bbd4820a59c8bd145ef6d0cfe +- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.30.1-pyhd8ed1ab_0.conda + sha256: bbbf409f50442f196debddcd0be5135c5fc6e25bd656185975383e0ee23b741d + md5: 04b12b1aef52ba590a7ec9a78c77a51a depends: - click >=7.0 - importlib-metadata >=4.6 @@ -6715,99 +6939,102 @@ packages: - mkdocs >=1.6 - mkdocs-autorefs >=1.4 - pymdown-extensions >=6.3 - - python >=3.9,<4.0 + - python >=3.10,<4.0 - typing-extensions >=4.1 license: ISC purls: - pkg:pypi/mkdocstrings?source=hash-mapping - size: 728508 - timestamp: 1743418701458 -- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.16.12-pyhff2d567_0.conda - sha256: f07f4a42bb13378305f2702905d35099838de83a235880017d1ae3a0fd401772 - md5: 6c3977dafc75737777349db98cd22d5e + size: 35475 + timestamp: 1758481651047 +- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.19.0-pyh332efcf_0.conda + sha256: b871393bb90694916ec1a943ae07b0953143fc479e3b55cf01fff091646bb96a + md5: 70e8b28bdb718ae28bcbc90aeeddcfbf depends: - - griffe >=1.6.2 + - griffe >=1.13 - mkdocs-autorefs >=1.4 - - mkdocstrings >=0.28.3 - - python >=3.9 + - mkdocstrings >=0.30 + - python >=3.10 - typing_extensions >=4.0 license: ISC purls: - pkg:pypi/mkdocstrings-python?source=hash-mapping - size: 58361 - timestamp: 1748965218001 -- conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda - sha256: 20e52b0389586d0b914a49cd286c5ccc9c47949bed60ca6df004d1d295f2edbd - md5: 302dff2807f2927b3e9e0d19d60121de - depends: - - intel-openmp 2024.* - - tbb 2021.* + size: 65585 + timestamp: 1762806569236 +- conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2025.3.0-hac47afa_454.conda + sha256: 3c432e77720726c6bd83e9ee37ac8d0e3dd7c4cf9b4c5805e1d384025f9e9ab6 + md5: c83ec81713512467dfe1b496a8292544 + depends: + - llvm-openmp >=21.1.4 + - tbb >=2022.2.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: LicenseRef-IntelSimplifiedSoftwareOct2022 license_family: Proprietary purls: [] - size: 103106385 - timestamp: 1730232843711 -- conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.7.0-pyhd8ed1ab_0.conda - sha256: d0c2253dcb1da6c235797b57d29de688dabc2e48cc49645b1cff2b52b7907428 - md5: 7c65a443d58beb0518c35b26c70e201d + size: 99909095 + timestamp: 1761668703167 +- conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.8.0-pyhd8ed1ab_0.conda + sha256: fabe81c8f8f3e1d0ef227fc1306526c76189b3f1175f12302c707e0972dd707c + md5: d7620a15dc400b448e1c88a981b23ddd depends: - - python >=3.9 + - python >=3.10 license: MIT license_family: MIT purls: - pkg:pypi/more-itertools?source=hash-mapping - size: 61359 - timestamp: 1745349566387 -- conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.1-py313h33d0bda_0.conda - sha256: b0e1b68a6e74d77986190f7296187c799a3f56119cb06663f7a57b15a7b1bd98 - md5: 009fb5ad03d4506be5f1e5c2f875f1c2 + size: 65129 + timestamp: 1756855971031 +- conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py313h7037e92_1.conda + sha256: fac37e267dd1d07527f0b078ffe000916e80e8c89cfe69d466f5775b88e93df2 + md5: cd1cfde0ea3bca6c805c73ffa988b12a depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 + - libgcc >=14 + - libstdcxx >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/msgpack?source=hash-mapping - size: 102677 - timestamp: 1749813320003 -- conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.1.1-py313ha0b1807_0.conda - sha256: a32167b77f2d18add251db808979c2918f3d4e59b97c66f4a982ad235528217e - md5: 65f4f9271a4e0f6049ee6b1ac4d9cf21 + size: 103129 + timestamp: 1762504205590 +- conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.1.2-py313h5eff275_1.conda + sha256: ac8d0cd48aace3fe3129e21ec0f1f37dd9548b048b04db492a5b7fddb1dea20c + md5: 44f1e465412acc4aeb8290acd756fb58 depends: - __osx >=10.13 - - libcxx >=18 + - libcxx >=19 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/msgpack?source=hash-mapping - size: 91394 - timestamp: 1749813473614 -- conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.1-py313h1ec8472_0.conda - sha256: 50a3f1bfcfa634538a2c0271bc9cd52d63a7933d5b4d56b16b176526af964108 - md5: 6a43d815d2b23ecfed7073c0706ac43d + size: 91891 + timestamp: 1762504487164 +- conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.2-py313hf069bd2_1.conda + sha256: 657fc62639dd638077f4d5e0bede9ed1bf4f4d018b395042bc36c9330e2c80fc + md5: 0013c110d17d569ce560b7fae6aee0d3 depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/msgpack?source=hash-mapping - size: 87496 - timestamp: 1749813653283 -- conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.16.1-py313h536fd9c_0.conda - sha256: 01f9acea3bc0fcdfc17acbe9ac003e18c4cccdaad3cdef7c3595e5c996b74324 - md5: 5446d84e248f2ac04f88af2c393383c6 + size: 88214 + timestamp: 1762504204957 +- conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.18.2-py313h07c4f96_0.conda + sha256: 7f3a86169171af4c13726ae81e0ac9e6730398bee169e4889c9e58691297bca4 + md5: d1975d5be0252584439d580d15434559 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - mypy_extensions >=1.0.0 - pathspec >=0.9.0 - psutil >=4.0 @@ -6818,11 +7045,11 @@ packages: license_family: MIT purls: - pkg:pypi/mypy?source=hash-mapping - size: 17242074 - timestamp: 1750118260507 -- conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.16.1-py313h63b0ddb_0.conda - sha256: 49cbef241c24b6e4f15b5cce30104fbe41151988456381d1b3037574c5014c7e - md5: 9d3e25c02eeea1904392d24df67ec9dc + size: 18026686 + timestamp: 1758278519618 +- conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.18.2-py313hf050af9_0.conda + sha256: 1947f4ab03af5cd61157d8cca5edeefdf5f3ebbe4689147598d2c0aae93c5fb6 + md5: 17cc4f27d88263457c008575d58bad6b depends: - __osx >=10.13 - mypy_extensions >=1.0.0 @@ -6835,11 +7062,11 @@ packages: license_family: MIT purls: - pkg:pypi/mypy?source=hash-mapping - size: 11269073 - timestamp: 1750118493594 -- conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.16.1-py313ha7868ed_0.conda - sha256: d915755801ee459c174dcd7d40ddc6b1a4b0e96fa161c686582223a3b51077f2 - md5: 7c94601304b4e66c082e9c86ad219cea + size: 11678265 + timestamp: 1758279032995 +- conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.18.2-py313h5ea7bf4_0.conda + sha256: 342bd9afea12d8016fab91297a604ad6f4a3f9e0fd112d9f62dfb0a462747e2b + md5: 8a1d0d6238a68322a36e806ea1f40a1d depends: - mypy_extensions >=1.0.0 - pathspec >=0.9.0 @@ -6848,14 +7075,14 @@ packages: - python_abi 3.13.* *_cp313 - typing_extensions >=4.6.0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: - pkg:pypi/mypy?source=hash-mapping - size: 8494415 - timestamp: 1750118712013 + size: 8648616 + timestamp: 1758278664539 - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda sha256: 6ed158e4e5dd8f6a10ad9e525631e35cee8557718f83de7a4e3966b1f772c4b1 md5: e9c622e0d00fa24a6292279af3ab6d06 @@ -6867,18 +7094,17 @@ packages: - pkg:pypi/mypy-extensions?source=hash-mapping size: 11766 timestamp: 1745776666688 -- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-1.44.0-pyhe01879c_0.conda - sha256: 2fdcf02863f5911ed438a92e301fe8308ecf2f1d5a2de85e4ebd45707e8047d5 - md5: e4d62696245e39222c5df7f903c7bf3a +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.11.0-pyhcf101f3_0.conda + sha256: 08956ad8e26aa96301a242a46ef768a83de73ce764ee0afb8264aab1210fa2b1 + md5: 5bf50f2d7bc9ee87a95ed3d1941664eb depends: - - python >=3.9 + - python >=3.10 - python license: MIT - license_family: MIT purls: - pkg:pypi/narwhals?source=compressed-mapping - size: 230314 - timestamp: 1750673052526 + size: 266834 + timestamp: 1762797637499 - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda sha256: a20cff739d66c2f89f413e4ba4c6f6b59c50d5c30b5f0d840c13e8c9c2df9135 md5: 6bb0d77277061742744176ab555b723c @@ -6894,20 +7120,20 @@ packages: - pkg:pypi/nbclient?source=hash-mapping size: 28045 timestamp: 1734628936013 -- conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hb482800_0.conda - sha256: 5480b7e05bf3079fcb7357a5a15a96c3a1649cc1371d0c468c806898a7e53088 - md5: aa90ea40c80d4bd3da35cb17ed668f22 +- conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hc388f54_1.conda + sha256: e151c45e9ad2b0368fe64f51b6c857873681df27da3c408a811e85551e129d0e + md5: 0b26dff819ba9cfb0f6ff9c8b6a53c19 depends: - - nbconvert-core ==7.16.6 pyh29332c3_0 - - nbconvert-pandoc ==7.16.6 hed9df3c_0 + - nbconvert-core ==7.16.6 pyhcf101f3_1 + - nbconvert-pandoc ==7.16.6 h7d6f222_1 license: BSD-3-Clause license_family: BSD purls: [] - size: 5241 - timestamp: 1738067871725 -- conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyh29332c3_0.conda - sha256: dcccb07c5a1acb7dc8be94330e62d54754c0e9c9cb2bb6865c8e3cfe44cf5a58 - md5: d24beda1d30748afcc87c429454ece1b + size: 5259 + timestamp: 1760797634451 +- conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda + sha256: 8f575e5c042b17f4677179a6ba474bdbe76573936d3d3e2aeb42b511b9cb1f3f + md5: cfc86ccc3b1de35d36ccaae4c50391f5 depends: - beautifulsoup4 - bleach-with-css !=5.0.0 @@ -6923,29 +7149,29 @@ packages: - packaging - pandocfilters >=1.4.1 - pygments >=2.4.1 - - python >=3.9 + - python >=3.10 - traitlets >=5.1 - python constrains: - pandoc >=2.9.2,<4.0.0 - - nbconvert ==7.16.6 *_0 + - nbconvert ==7.16.6 *_1 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/nbconvert?source=hash-mapping - size: 200601 - timestamp: 1738067871724 -- conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.6-hed9df3c_0.conda - sha256: 1e8923f1557c2ddb7bba915033cfaf8b8c1b7462c745172458102c11caee1002 - md5: 5b0afb6c52e74a7eca2cf809a874acf4 + - pkg:pypi/nbconvert?source=compressed-mapping + size: 199273 + timestamp: 1760797634443 +- conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.6-h7d6f222_1.conda + sha256: 1eaf769838863544a0f2d2fb05acba1211a764b64234b53b2da836015d661150 + md5: 32b4a67e7fde3b22287b65838c8ad01b depends: - - nbconvert-core ==7.16.6 pyh29332c3_0 + - nbconvert-core ==7.16.6 pyhcf101f3_1 - pandoc license: BSD-3-Clause license_family: BSD purls: [] - size: 5722 - timestamp: 1738067871725 + size: 5726 + timestamp: 1760797634451 - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda sha256: 7a5bd30a2e7ddd7b85031a5e2e14f290898098dc85bea5b3a5bf147c25122838 md5: bbe1963f1e47f594070ffe87cdf612ea @@ -6991,38 +7217,42 @@ packages: - pkg:pypi/nest-asyncio?source=hash-mapping size: 11543 timestamp: 1733325673691 -- conda: https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h3f2d84a_0.conda - sha256: e2fc624d6f9b2f1b695b6be6b905844613e813aa180520e73365062683fe7b49 - md5: d76872d096d063e226482c99337209dc +- conda: https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda + sha256: fd2cbd8dfc006c72f45843672664a8e4b99b2f8137654eaae8c3d46dca776f63 + md5: 16c2a0e9c4a166e53632cfca4f68d020 + constrains: + - nlohmann_json-abi ==3.12.0 license: MIT license_family: MIT purls: [] - size: 135906 - timestamp: 1744445169928 -- conda: https://conda.anaconda.org/conda-forge/osx-64/nlohmann_json-3.12.0-h92383a6_0.conda - sha256: b3bcb65c023d2e9f5e5e809687cfede587cc71ea9f037c45b1f87727003583db - md5: 9334c0f8d63ac55ff03e3b9cef9e371c + size: 136216 + timestamp: 1758194284857 +- conda: https://conda.anaconda.org/conda-forge/osx-64/nlohmann_json-3.12.0-h53ec75d_1.conda + sha256: 186edb5fe84bddf12b5593377a527542f6ba42486ca5f49cd9dfeda378fb0fbe + md5: 5e9bee5fa11d91e1621e477c3cb9b9ba + constrains: + - nlohmann_json-abi ==3.12.0 license: MIT license_family: MIT purls: [] - size: 136237 - timestamp: 1744445192082 -- conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.4.3-pyhd8ed1ab_0.conda - sha256: aea1b33b734e809bd090f0bae47f4bca5da406f7bc7dd65a67b565f03c740866 - md5: f0b767b717cab652712d29f5e4699b2a + size: 136667 + timestamp: 1758194361656 +- conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.4.7-pyhd8ed1ab_0.conda + sha256: 9d785a993dd149cae89382e24dfc234bf0295d310a34ca8288818c401c097d40 + md5: 8265e246510553a4bcec1af4378d3c96 depends: - jupyter_server >=2.4.0,<3 - - jupyterlab >=4.4.3,<4.5 + - jupyterlab >=4.4.9,<4.5 - jupyterlab_server >=2.27.1,<3 - notebook-shim >=0.2,<0.3 - - python >=3.9 + - python >=3.10 - tornado >=6.2.0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/notebook?source=hash-mapping - size: 10538691 - timestamp: 1748278796079 + size: 10391640 + timestamp: 1759152183508 - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda sha256: 7b920e46b9f7a2d2aa6434222e5c8d739021dbc5cc75f32d124a8191d86f9056 md5: e7f89ea5f7ea9401642758ff50a2d9c1 @@ -7035,16 +7265,16 @@ packages: - pkg:pypi/notebook-shim?source=hash-mapping size: 16817 timestamp: 1733408419340 -- conda: https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.16.1-py313ha87cce1_0.conda - sha256: 9f95245cf166a4777da4b6c8bbedf2b4bc96962e84a8ec0bfe323b79229a1556 - md5: 1a2c7ab508d5c7ae876bf7e064a1e0cf +- conda: https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.16.1-py313h08cd8bf_2.conda + sha256: 5ff756ee38c4e7d13230703f7f8ee017df6217aa783b841a1642845804573e01 + md5: 9b0bbd18cd7c0ac846810433191e7078 depends: - __glibc >=2.17,<3.0.a0 - deprecated - - libgcc >=13 - - libstdcxx >=13 + - libgcc >=14 + - libstdcxx >=14 - msgpack-python - - numpy >=1.21,<3 + - numpy >=1.23,<3 - numpy >=1.24 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 @@ -7053,17 +7283,17 @@ packages: license_family: MIT purls: - pkg:pypi/numcodecs?source=hash-mapping - size: 818138 - timestamp: 1747933291791 -- conda: https://conda.anaconda.org/conda-forge/osx-64/numcodecs-0.16.1-py313h2e7108f_0.conda - sha256: b4b474779cc6228d7a8827f3705f818d4441fe446200461fa778d3f6fae112a9 - md5: 24832935d42586aca61bc166d6450004 + size: 818047 + timestamp: 1759814333161 +- conda: https://conda.anaconda.org/conda-forge/osx-64/numcodecs-0.16.1-py313h2f264a9_2.conda + sha256: 9d03423201aab50f8c7f8b8c715caf64148ad1ebce4558751d5acaf8d36d5502 + md5: d3d2ded23172ee35edfb98b20ff576c5 depends: - __osx >=10.13 - deprecated - - libcxx >=18 + - libcxx >=19 - msgpack-python - - numpy >=1.21,<3 + - numpy >=1.23,<3 - numpy >=1.24 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 @@ -7072,220 +7302,224 @@ packages: license_family: MIT purls: - pkg:pypi/numcodecs?source=hash-mapping - size: 757861 - timestamp: 1747933398435 -- conda: https://conda.anaconda.org/conda-forge/win-64/numcodecs-0.16.1-py313hf91d08e_0.conda - sha256: c6673e26beb2e9a6eb1a715c1b711cd11d1cf75d65f478412c2795657b12aa45 - md5: d0419f5b6c0ecfd1f8c2272117fcfe9b + size: 759162 + timestamp: 1759814798321 +- conda: https://conda.anaconda.org/conda-forge/win-64/numcodecs-0.16.1-py313hc90dcd4_2.conda + sha256: d6f7fe60fa90a19f4fb464a6f9347583c519e7749bd7f008d03dcae5a432dd53 + md5: 90567ede3e975ffaf8c5fd85441ea756 depends: - deprecated - msgpack-python - - numpy >=1.21,<3 + - numpy >=1.23,<3 - numpy >=1.24 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - typing_extensions - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: - pkg:pypi/numcodecs?source=hash-mapping - size: 510178 - timestamp: 1747933816910 -- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.0-py313h17eae1a_0.conda - sha256: 8b88ade24df5229c5d76c5ef09568ae4630b1095982e94648fbbeb18f475aa61 - md5: db18a34466bef0863e9301b518a75e8f + size: 514951 + timestamp: 1759814346546 +- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.4-py313hf6604e3_0.conda + sha256: 41084b68fbbcbaba0bce28872ec338371f4ccbe40a5464eb8bed2c694197faa5 + md5: c47c527e215377958d28c470ce4863e1 depends: + - python + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libblas >=3.9.0,<4.0a0 - - libcblas >=3.9.0,<4.0a0 - - libgcc >=13 + - libstdcxx >=14 + - libgcc >=14 - liblapack >=3.9.0,<4.0a0 - - libstdcxx >=13 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 + - libcblas >=3.9.0,<4.0a0 + - libblas >=3.9.0,<4.0a0 constrains: - numpy-base <0a0 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/numpy?source=hash-mapping - size: 8545037 - timestamp: 1749430954481 -- conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.3.0-py313hc518a0f_0.conda - sha256: 6e751f573b6aa727b83bdcb6534c9a4ffe05bcb56a659eb3f1418d28794213cc - md5: 9ff00ee247ea2b114a56de1a31a5d5af + - pkg:pypi/numpy?source=compressed-mapping + size: 8889991 + timestamp: 1761162144475 +- conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.3.4-py313ha99c057_0.conda + sha256: 97856ffabea4a84badba72515178ad9cf5e8def837203e97bf78a59ce21c8b5f + md5: 8f1926ac8ba86847cde84b477b1bdf4d depends: + - python - __osx >=10.13 - - libblas >=3.9.0,<4.0a0 - - libcblas >=3.9.0,<4.0a0 - - libcxx >=18 + - libcxx >=19 - liblapack >=3.9.0,<4.0a0 - - python >=3.13,<3.14.0a0 + - libblas >=3.9.0,<4.0a0 - python_abi 3.13.* *_cp313 + - libcblas >=3.9.0,<4.0a0 constrains: - numpy-base <0a0 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/numpy?source=compressed-mapping - size: 7634474 - timestamp: 1749431208151 -- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.3.0-py313hefb8edb_0.conda - sha256: b2d8af00021061b43fc43f24ad7f135ff3641bc642e25dab0a175126facb749b - md5: 34a477d1a0c5396c6d82d6f7765ca339 + - pkg:pypi/numpy?source=hash-mapping + size: 8038084 + timestamp: 1761161603414 +- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.3.4-py313hce7ae62_0.conda + sha256: 0ab0c3a5fb404f5a501506aca0cc7eeb5be92bd3ce6d4811dbd7963ed330d33f + md5: 348041d099d11ab630124d7135bf233a depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - liblapack >=3.9.0,<4.0a0 - libblas >=3.9.0,<4.0a0 - libcblas >=3.9.0,<4.0a0 - - liblapack >=3.9.0,<4.0a0 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 constrains: - numpy-base <0a0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/numpy?source=hash-mapping - size: 6646194 - timestamp: 1749431079208 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda - sha256: 5bee706ea5ba453ed7fd9da7da8380dd88b865c8d30b5aaec14d2b6dd32dbc39 - md5: 9e5816bc95d285c115a3ebc2f8563564 + size: 7461895 + timestamp: 1761161591941 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda + sha256: 3900f9f2dbbf4129cf3ad6acf4e4b6f7101390b53843591c53b00f034343bc4d + md5: 11b3379b191f63139e29c0d19dee24cd depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libpng >=1.6.44,<1.7.0a0 - - libstdcxx >=13 - - libtiff >=4.7.0,<4.8.0a0 + - libgcc >=14 + - libpng >=1.6.50,<1.7.0a0 + - libstdcxx >=14 + - libtiff >=4.7.1,<4.8.0a0 - libzlib >=1.3.1,<2.0a0 license: BSD-2-Clause license_family: BSD purls: [] - size: 342988 - timestamp: 1733816638720 -- conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.3-h7fd6d84_0.conda - sha256: faea03f36c9aa3524c911213b116da41695ff64b952d880551edee2843fe115b - md5: 025c711177fc3309228ca1a32374458d + size: 355400 + timestamp: 1758489294972 +- conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h87e8dc5_0.conda + sha256: fdf4708a4e45b5fd9868646dd0c0a78429f4c0b8be490196c975e06403a841d0 + md5: a67d3517ebbf615b91ef9fdc99934e0c depends: - __osx >=10.13 - - libcxx >=18 - - libpng >=1.6.44,<1.7.0a0 - - libtiff >=4.7.0,<4.8.0a0 + - libcxx >=19 + - libpng >=1.6.50,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 - libzlib >=1.3.1,<2.0a0 license: BSD-2-Clause license_family: BSD purls: [] - size: 332320 - timestamp: 1733816828284 -- conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.3-h4d64b90_0.conda - sha256: 410175815df192f57a07c29a6b3fdd4231937173face9e63f0830c1234272ce3 - md5: fc050366dd0b8313eb797ed1ffef3a29 + size: 334875 + timestamp: 1758489493148 +- conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h24db6dd_0.conda + sha256: 226c270a7e3644448954c47959c00a9bf7845f6d600c2a643db187118d028eee + md5: 5af852046226bb3cb15c7f61c2ac020a depends: - - libpng >=1.6.44,<1.7.0a0 - - libtiff >=4.7.0,<4.8.0a0 + - libpng >=1.6.50,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 - libzlib >=1.3.1,<2.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: BSD-2-Clause license_family: BSD purls: [] - size: 240148 - timestamp: 1733817010335 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda - sha256: b4491077c494dbf0b5eaa6d87738c22f2154e9277e5293175ec187634bd808a0 - md5: de356753cfdbffcde5bb1e86e3aa6cd0 + size: 244860 + timestamp: 1758489556249 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda + sha256: a47271202f4518a484956968335b2521409c8173e123ab381e775c358c67fe6d + md5: 9ee58d5c534af06558933af3c845a780 depends: - __glibc >=2.17,<3.0.a0 - ca-certificates - - libgcc >=13 + - libgcc >=14 license: Apache-2.0 license_family: Apache purls: [] - size: 3117410 - timestamp: 1746223723843 -- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.5.0-hc426f3f_1.conda - sha256: bcac94cb82a458b4e3164da8d9bced08cc8c3da2bc3bd7330711a3689c1464a5 - md5: 919faa07b9647beb99a0e7404596a465 + size: 3165399 + timestamp: 1762839186699 +- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda + sha256: 36fe9fb316be22fcfb46d5fa3e2e85eec5ef84f908b7745f68f768917235b2d5 + md5: 3f50cdf9a97d0280655758b735781096 depends: - __osx >=10.13 - ca-certificates license: Apache-2.0 license_family: Apache purls: [] - size: 2739181 - timestamp: 1746224401118 -- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.5.0-ha4e3fda_1.conda - sha256: 02846553d2a4c9bde850c60824d0f02803eb9c9b674d5c1a8cce25bc387e748f - md5: 72c07e46b6766bb057018a9a74861b89 + size: 2778996 + timestamp: 1762840724922 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda + sha256: 6d72d6f766293d4f2aa60c28c244c8efed6946c430814175f959ffe8cab899b3 + md5: 84f8fb4afd1157f59098f618cd2437e4 depends: - ca-certificates - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: Apache purls: [] - size: 9025176 - timestamp: 1746227349882 -- conda: https://conda.anaconda.org/conda-forge/linux-64/orc-2.1.2-h17f744e_0.conda - sha256: f6ff644e27f42f2beb877773ba3adc1228dbb43530dbe9426dd672f3b847c7c5 - md5: ef7f9897a244b2023a066c22a1089ce4 + size: 9440812 + timestamp: 1762841722179 +- conda: https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.1-hd747db4_0.conda + sha256: 8d91d6398fc63a94d238e64e4983d38f6f9555460f11bed00abb2da04dbadf7c + md5: ddab8b2af55b88d63469c040377bd37e depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libprotobuf >=5.29.3,<5.29.4.0a0 - - libstdcxx >=13 + - libgcc >=14 + - libprotobuf >=6.31.1,<6.31.2.0a0 + - libstdcxx >=14 - libzlib >=1.3.1,<2.0a0 - lz4-c >=1.10.0,<1.11.0a0 - - snappy >=1.2.1,<1.3.0a0 + - snappy >=1.2.2,<1.3.0a0 - tzdata - zstd >=1.5.7,<1.6.0a0 license: Apache-2.0 license_family: Apache purls: [] - size: 1242887 - timestamp: 1746604310927 -- conda: https://conda.anaconda.org/conda-forge/osx-64/orc-2.1.2-h82caab2_0.conda - sha256: f09b8f1c857e58f80f1b36405c267426c7d72866b2df68195c46f714ea93c6aa - md5: 6ed7bb177d311ceb0ba22f56a2762a58 + size: 1316445 + timestamp: 1759424644934 +- conda: https://conda.anaconda.org/conda-forge/osx-64/orc-2.2.1-hd1b02dc_0.conda + sha256: a00d48750d2140ea97d92b32c171480b76b2632dbb9d19d1ae423999efcc825f + md5: b4646b6ddcbcb3b10e9879900c66ed48 depends: - - __osx >=10.14 - - libcxx >=18 - - libprotobuf >=5.29.3,<5.29.4.0a0 + - __osx >=11.0 + - libcxx >=19 + - libprotobuf >=6.31.1,<6.31.2.0a0 - libzlib >=1.3.1,<2.0a0 - lz4-c >=1.10.0,<1.11.0a0 - - snappy >=1.2.1,<1.3.0a0 + - snappy >=1.2.2,<1.3.0a0 - tzdata - zstd >=1.5.7,<1.6.0a0 license: Apache-2.0 license_family: Apache purls: [] - size: 508795 - timestamp: 1746604387916 -- conda: https://conda.anaconda.org/conda-forge/win-64/orc-2.1.2-h35764e3_0.conda - sha256: 1129e9f4346db6bfad7774bc66459913f6ea190e3be33a4632148745db874c65 - md5: 9d1fedcfc170bc82edc7f90f5dc30233 + size: 521463 + timestamp: 1759424838652 +- conda: https://conda.anaconda.org/conda-forge/win-64/orc-2.2.1-h7414dfc_0.conda + sha256: f28f8f2d743c2091f76161b8d59f82c4ba4970d03cb9900c52fb908fe5e8a7c4 + md5: a9b6ebf475194b0e5ad43168e9b936a7 depends: - - libprotobuf >=5.29.3,<5.29.4.0a0 + - libprotobuf >=6.31.1,<6.31.2.0a0 - libzlib >=1.3.1,<2.0a0 - lz4-c >=1.10.0,<1.11.0a0 - - snappy >=1.2.1,<1.3.0a0 + - snappy >=1.2.2,<1.3.0a0 - tzdata - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - zstd >=1.5.7,<1.6.0a0 license: Apache-2.0 license_family: Apache purls: [] - size: 1111604 - timestamp: 1746604806856 + size: 1064397 + timestamp: 1759424869069 - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda sha256: 1840bd90d25d4930d60f57b4f38d4e0ae3f5b8db2819638709c36098c6ba770c md5: e51f1e4089cad105b6cac64bd8166587 @@ -7307,7 +7541,7 @@ packages: license: Apache-2.0 license_family: APACHE purls: - - pkg:pypi/packaging?source=compressed-mapping + - pkg:pypi/packaging?source=hash-mapping size: 62477 timestamp: 1745345660407 - conda: https://conda.anaconda.org/conda-forge/noarch/paginate-0.5.7-pyhd8ed1ab_1.conda @@ -7321,185 +7555,185 @@ packages: - pkg:pypi/paginate?source=hash-mapping size: 18865 timestamp: 1734618649164 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.0-py313ha87cce1_0.conda - sha256: c4a6e9bc13454c5afd17600c2ee2b6b07fee8b2629cb1c193c22c048faa9bdcc - md5: 8664b4fa9b5b23b0d1cdc55c7195fcfe +- conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_1.conda + sha256: c4ce5f75d175cb264dc98af6db14378222b63955c63bf1b5e30e042e81624fae + md5: 9e87d4bda0c2711161d765332fa38781 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - - numpy >=1.21,<3 + - libgcc >=14 + - libstdcxx >=14 - numpy >=1.22.4 + - numpy >=1.23,<3 - python >=3.13,<3.14.0a0 - python-dateutil >=2.8.2 - python-tzdata >=2022.7 - python_abi 3.13.* *_cp313 - pytz >=2020.1 constrains: - - zstandard >=0.19.0 - - sqlalchemy >=2.0.0 - - pyqt5 >=5.15.9 - - pyxlsb >=1.0.10 - - qtpy >=2.3.0 + - xlrd >=2.0.1 + - scipy >=1.10.0 + - fsspec >=2022.11.0 - odfpy >=1.4.1 + - beautifulsoup4 >=4.11.2 - python-calamine >=0.1.7 - - pytables >=3.8.0 - numexpr >=2.8.4 - - s3fs >=2022.11.0 - - html5lib >=1.1 - - pyarrow >=10.0.1 + - pytables >=3.8.0 + - pandas-gbq >=0.19.0 + - tzdata >=2022.7 + - pyxlsb >=1.0.10 - xarray >=2022.12.0 + - pyqt5 >=5.15.9 - lxml >=4.9.2 - - openpyxl >=3.1.0 - - fastparquet >=2022.12.0 - - fsspec >=2022.11.0 - matplotlib >=3.6.3 - - scipy >=1.10.0 - - pandas-gbq >=0.19.0 - - xlsxwriter >=3.0.5 - - blosc >=1.21.3 - - xlrd >=2.0.1 + - openpyxl >=3.1.0 + - qtpy >=2.3.0 + - psycopg2 >=2.9.6 + - pyarrow >=10.0.1 + - tabulate >=0.9.0 + - zstandard >=0.19.0 + - html5lib >=1.1 - bottleneck >=1.3.6 - numba >=0.56.4 - - beautifulsoup4 >=4.11.2 + - sqlalchemy >=2.0.0 - pyreadstat >=1.2.0 - - tabulate >=0.9.0 - - tzdata >=2022.7 - gcsfs >=2022.11.0 - - psycopg2 >=2.9.6 + - fastparquet >=2022.12.0 + - s3fs >=2022.11.0 + - blosc >=1.21.3 + - xlsxwriter >=3.0.5 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/pandas?source=hash-mapping - size: 14991000 - timestamp: 1749100101435 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.0-py313h2e7108f_0.conda - sha256: e403af69c29fc477a1857a60a77b7e33063ca07b9c312818a820adcb29ab948e - md5: 54635bd0e921609f8331e07cf6344a90 + size: 15131510 + timestamp: 1759266202915 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.3-py313h2f264a9_1.conda + sha256: 4fe8cb4e528e83f74e4f9f4277e4464eefcab2c93bb3b2509564bbb903597efa + md5: edd7a9cfba45ab3073b594ec999a24fe depends: - __osx >=10.13 - - libcxx >=18 - - numpy >=1.21,<3 + - libcxx >=19 - numpy >=1.22.4 + - numpy >=1.23,<3 - python >=3.13,<3.14.0a0 - python-dateutil >=2.8.2 - python-tzdata >=2022.7 - python_abi 3.13.* *_cp313 - pytz >=2020.1 constrains: - - xlsxwriter >=3.0.5 - - html5lib >=1.1 - - s3fs >=2022.11.0 - - tabulate >=0.9.0 - - psycopg2 >=2.9.6 - - beautifulsoup4 >=4.11.2 - - odfpy >=1.4.1 - - xarray >=2022.12.0 - - zstandard >=0.19.0 - - python-calamine >=0.1.7 - - pyreadstat >=1.2.0 - - xlrd >=2.0.1 - - blosc >=1.21.3 + - pandas-gbq >=0.19.0 + - matplotlib >=3.6.3 - fsspec >=2022.11.0 - - pyqt5 >=5.15.9 - - numexpr >=2.8.4 - - sqlalchemy >=2.0.0 + - tzdata >=2022.7 + - pytables >=3.8.0 - scipy >=1.10.0 - - pandas-gbq >=0.19.0 - - openpyxl >=3.1.0 + - pyreadstat >=1.2.0 + - numexpr >=2.8.4 - pyarrow >=10.0.1 + - odfpy >=1.4.1 - qtpy >=2.3.0 - - pytables >=3.8.0 - - tzdata >=2022.7 - - bottleneck >=1.3.6 + - tabulate >=0.9.0 + - lxml >=4.9.2 + - zstandard >=0.19.0 + - s3fs >=2022.11.0 + - html5lib >=1.1 + - blosc >=1.21.3 + - pyqt5 >=5.15.9 - pyxlsb >=1.0.10 - - fastparquet >=2022.12.0 - numba >=0.56.4 - - lxml >=4.9.2 + - xarray >=2022.12.0 + - fastparquet >=2022.12.0 + - bottleneck >=1.3.6 - gcsfs >=2022.11.0 - - matplotlib >=3.6.3 + - beautifulsoup4 >=4.11.2 + - openpyxl >=3.1.0 + - xlsxwriter >=3.0.5 + - xlrd >=2.0.1 + - sqlalchemy >=2.0.0 + - python-calamine >=0.1.7 + - psycopg2 >=2.9.6 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/pandas?source=hash-mapping - size: 14196191 - timestamp: 1749100236221 -- conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.3.0-py313hf91d08e_0.conda - sha256: 2dac0e788df070dfb12e7f3630386973b0bb9730d04b7f774c519e3f3f1db21f - md5: 06f537fc2102679d5c1567cf2d38391d + size: 14330563 + timestamp: 1759266231408 +- conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.3.3-py313hc90dcd4_1.conda + sha256: 4117c0ecf6ac2544d956038446df70884b48cf745cf50a28872cec54d189d6f8 + md5: 72e76484d7629ec9217e71d9c6281e09 depends: - - numpy >=1.21,<3 - numpy >=1.22.4 - - python >=3.13,<3.14.0a0 - - python-dateutil >=2.8.2 - - python-tzdata >=2022.7 - - python_abi 3.13.* *_cp313 - - pytz >=2020.1 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - constrains: - - pytables >=3.8.0 - - scipy >=1.10.0 - - xlsxwriter >=3.0.5 - - sqlalchemy >=2.0.0 - - tzdata >=2022.7 - - python-calamine >=0.1.7 - - pyqt5 >=5.15.9 - - s3fs >=2022.11.0 - - zstandard >=0.19.0 - - qtpy >=2.3.0 - - matplotlib >=3.6.3 + - numpy >=1.23,<3 + - python >=3.13,<3.14.0a0 + - python-dateutil >=2.8.2 + - python-tzdata >=2022.7 + - python_abi 3.13.* *_cp313 + - pytz >=2020.1 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: - xlrd >=2.0.1 + - numba >=0.56.4 + - zstandard >=0.19.0 - odfpy >=1.4.1 - - pyxlsb >=1.0.10 - - pandas-gbq >=0.19.0 - - fastparquet >=2022.12.0 - openpyxl >=3.1.0 - - tabulate >=0.9.0 - - gcsfs >=2022.11.0 - bottleneck >=1.3.6 - numexpr >=2.8.4 + - tzdata >=2022.7 + - html5lib >=1.1 + - gcsfs >=2022.11.0 + - qtpy >=2.3.0 + - xlsxwriter >=3.0.5 + - s3fs >=2022.11.0 + - tabulate >=0.9.0 + - xarray >=2022.12.0 + - pandas-gbq >=0.19.0 + - lxml >=4.9.2 + - pyqt5 >=5.15.9 - pyarrow >=10.0.1 - - beautifulsoup4 >=4.11.2 + - pytables >=3.8.0 + - pyxlsb >=1.0.10 - pyreadstat >=1.2.0 - - lxml >=4.9.2 - - xarray >=2022.12.0 - - html5lib >=1.1 - - numba >=0.56.4 + - scipy >=1.10.0 - fsspec >=2022.11.0 - - psycopg2 >=2.9.6 + - matplotlib >=3.6.3 + - sqlalchemy >=2.0.0 + - beautifulsoup4 >=4.11.2 - blosc >=1.21.3 + - psycopg2 >=2.9.6 + - fastparquet >=2022.12.0 + - python-calamine >=0.1.7 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/pandas?source=hash-mapping - size: 13929307 - timestamp: 1749100343118 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.8.2-ha770c72_0.conda - sha256: ae3760e865327aaf95df025ccea9ddc1d80ab9f70c5d2478bbfbf324b8eb4e7d - md5: 4c9317a85d1c233f490545392e895118 + size: 13956530 + timestamp: 1759266304527 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.8.2.1-ha770c72_0.conda + sha256: 6b92e15cbc84ce4a0171ca0a9b9f483888a9065b17302d1503c0cacfcf8abd56 + md5: 47432e6a6fb5d9697564185e1907138a license: GPL-2.0-or-later license_family: GPL purls: [] - size: 22001565 - timestamp: 1759744608086 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pandoc-3.8.2-h694c41f_0.conda - sha256: 6dc48341fc550b56bc1da8a6354ebc05f5583da38589ba7c0d5b1b8d275d094a - md5: b8cb588161a247b8e8aade0797d44e60 + size: 22018364 + timestamp: 1760964197643 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pandoc-3.8.2.1-h694c41f_0.conda + sha256: 094e55a7dc5f95d7dd76547d69bf9bae2080276c378e720428eba65c54dbb5aa + md5: 5a4bd7ee9f84abfddc2fa314dd8e160c license: GPL-2.0-or-later license_family: GPL purls: [] - size: 16601429 - timestamp: 1759744812255 -- conda: https://conda.anaconda.org/conda-forge/win-64/pandoc-3.8.2-h57928b3_0.conda - sha256: ff55de733e42d44f10372f1707e1579bdc56edb6e8b72ab80e6306d9073299b1 - md5: 88a11dca037752f036fafb414dd8e0b0 + size: 16613352 + timestamp: 1760964384346 +- conda: https://conda.anaconda.org/conda-forge/win-64/pandoc-3.8.2.1-h57928b3_0.conda + sha256: e39ce8d67c6cb925cd148c730a1335c56075fa4ff6e902c3d1b7ad04c9078832 + md5: 69c8325067e9ff3bab5715d673f99636 license: GPL-2.0-or-later license_family: GPL purls: [] - size: 26145406 - timestamp: 1759744715153 + size: 26155900 + timestamp: 1760964354207 - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 sha256: 2bb9ba9857f4774b85900c2562f7e711d08dd48e2add9bee4e1612fbee27e16f md5: 457c2c8c08e54905d6954e79cb5b5db9 @@ -7511,16 +7745,17 @@ packages: - pkg:pypi/pandocfilters?source=hash-mapping size: 11627 timestamp: 1631603397334 -- conda: https://conda.anaconda.org/conda-forge/noarch/panel-1.7.1-pyhd8ed1ab_0.conda - sha256: 039d170994573f9731960c152a65c3a3eab0f8c2170057ff0ef0e58de0fc63f6 - md5: ce7149f1fc36e23ae60ba5a70a249c67 +- conda: https://conda.anaconda.org/conda-forge/noarch/panel-1.8.3-pyhd8ed1ab_0.conda + sha256: 39d64deee495c8bd00f260791d5ee5f871af92d184423144e1eb5cb24c8da9c8 + md5: b67a3487322940b0fcd80860ec78f717 depends: - bleach - - bokeh >=3.5.0,<3.8.0 + - bokeh >=3.7.0,<3.9.0 - linkify-it-py - markdown - markdown-it-py - mdit-py-plugins + - narwhals >=2 - packaging - pandas >=1.2 - param >=2.1.0,<3.0 @@ -7532,11 +7767,10 @@ packages: constrains: - holoviews >=1.18.0 license: BSD-3-Clause - license_family: BSD purls: - - pkg:pypi/panel?source=hash-mapping - size: 22597806 - timestamp: 1748429471635 + - pkg:pypi/panel?source=compressed-mapping + size: 22903699 + timestamp: 1762779744606 - conda: https://conda.anaconda.org/conda-forge/noarch/param-2.2.1-pyhd8ed1ab_0.conda sha256: 2dc5b1f066e283d23678ef6484fa2fdaebe9db6a6d83905f7fc9233dc65ceba0 md5: b6f8a6ac73c7d5fdc5efc206ac8c98c4 @@ -7548,17 +7782,18 @@ packages: - pkg:pypi/param?source=hash-mapping size: 105120 timestamp: 1749664822292 -- conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_1.conda - sha256: 17131120c10401a99205fc6fe436e7903c0fa092f1b3e80452927ab377239bcc - md5: 5c092057b6badd30f75b06244ecd01c9 +- conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.5-pyhcf101f3_0.conda + sha256: 30de7b4d15fbe53ffe052feccde31223a236dae0495bab54ab2479de30b2990f + md5: a110716cdb11cf51482ff4000dc253d7 depends: - - python >=3.9 + - python >=3.10 + - python license: MIT license_family: MIT purls: - pkg:pypi/parso?source=hash-mapping - size: 75295 - timestamp: 1733271352153 + size: 81562 + timestamp: 1755974222274 - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda sha256: 472fc587c63ec4f6eba0cc0b06008a6371e0a08a5986de3cf4e8024a47b4fe6c md5: 0badf9c54e24cecfb0ad2f99d680c163 @@ -7583,19 +7818,19 @@ packages: - pkg:pypi/pathspec?source=hash-mapping size: 41075 timestamp: 1733233471940 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.45-hc749103_0.conda - sha256: 27c4014f616326240dcce17b5f3baca3953b6bc5f245ceb49c3fa1e6320571eb - md5: b90bece58b4c2bf25969b70f3be42d25 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda + sha256: 5c7380c8fd3ad5fc0f8039069a45586aa452cf165264bc5a437ad80397b32934 + md5: 7fa07cb0fb1b625a089ccc01218ee5b1 depends: - __glibc >=2.17,<3.0.a0 - bzip2 >=1.0.8,<2.0a0 - - libgcc >=13 + - libgcc >=14 - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD purls: [] - size: 1197308 - timestamp: 1745955064657 + size: 1209177 + timestamp: 1756742976157 - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda sha256: 202af1de83b585d36445dc1fda94266697341994d1a3328fabde4989e1b3d07a md5: d0d408b1f18883a944376da5cf8101ea @@ -7604,100 +7839,92 @@ packages: - python >=3.9 license: ISC purls: - - pkg:pypi/pexpect?source=compressed-mapping + - pkg:pypi/pexpect?source=hash-mapping size: 53561 timestamp: 1733302019362 -- conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - sha256: e2ac3d66c367dada209fc6da43e645672364b9fd5f9d28b9f016e24b81af475b - md5: 11a9d1d09a3615fc07c3faf79bc0b943 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pickleshare?source=hash-mapping - size: 11748 - timestamp: 1733327448200 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py313h8db990d_0.conda - sha256: f35e9bef2dd00361b871deb015cd50c3ff2847b957af16ab98651443eab1010c - md5: 91b00afee98d72d29dc3d1c1ab0008d7 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py313h50355cd_0.conda + sha256: f4f7554212aa3ca89ff2336f6312dc61c81b9f7364073fe74374d96fc81391b7 + md5: 8a96eab78687362de3e102a15c4747a8 depends: + - python + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - lcms2 >=2.17,<3.0a0 - - libfreetype >=2.13.3 - - libfreetype6 >=2.13.3 - - libgcc >=13 - - libjpeg-turbo >=3.1.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libwebp-base >=1.5.0,<2.0a0 - libxcb >=1.17.0,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - openjpeg >=2.5.3,<3.0a0 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 + - lcms2 >=2.17,<3.0a0 - tk >=8.6.13,<8.7.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - openjpeg >=2.5.4,<3.0a0 + - zlib-ng >=2.2.5,<2.3.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 license: HPND purls: - pkg:pypi/pillow?source=compressed-mapping - size: 42836283 - timestamp: 1746646372487 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pillow-11.2.1-py313h0c4f865_0.conda - sha256: 8bf95b09c3884b571b47e26dd00220311bc9bdcbd7c7620854e2ff556aba450c - md5: b4647eda8779d0e5d25cc8c9b124b303 + size: 1040440 + timestamp: 1761655794834 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pillow-12.0.0-py313he918548_0.conda + sha256: dcf8961767f0fd2f8df37eef74eb573466407d9cb92a8dce9f6201874dd0ce42 + md5: 07751e2d8586d5fc1d000b48756cf6ee depends: + - python - __osx >=10.13 - lcms2 >=2.17,<3.0a0 - - libfreetype >=2.13.3 - - libfreetype6 >=2.13.3 - - libjpeg-turbo >=3.1.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libwebp-base >=1.5.0,<2.0a0 - - libxcb >=1.17.0,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - openjpeg >=2.5.3,<3.0a0 - - python >=3.13,<3.14.0a0 + - zlib-ng >=2.2.5,<2.3.0a0 - python_abi 3.13.* *_cp313 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libwebp-base >=1.6.0,<2.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 - tk >=8.6.13,<8.7.0a0 + - openjpeg >=2.5.4,<3.0a0 + - libxcb >=1.17.0,<2.0a0 license: HPND purls: - pkg:pypi/pillow?source=hash-mapping - size: 42452203 - timestamp: 1746646509719 -- conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.2.1-py313hda88b71_0.conda - sha256: b5b0074dae2c2064e124c94cfea0029dd04122a7bb90552e739900867061eb31 - md5: 04f15a89396af43b697fd583fe37863a + size: 975053 + timestamp: 1761655892835 +- conda: https://conda.anaconda.org/conda-forge/win-64/pillow-12.0.0-py313hf6db949_0.conda + sha256: 71e0c2315ae8db4a45dbd7e6224f65ea6c7deaa705469679f3b4a30d4c6f2395 + md5: 89bc86b7c8999fc3904526fcebe5712d depends: - - lcms2 >=2.17,<3.0a0 - - libfreetype >=2.13.3 - - libfreetype6 >=2.13.3 + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libwebp-base >=1.6.0,<2.0a0 + - openjpeg >=2.5.4,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - python_abi 3.13.* *_cp313 - libjpeg-turbo >=3.1.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libwebp-base >=1.5.0,<2.0a0 - libxcb >=1.17.0,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - openjpeg >=2.5.3,<3.0a0 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - lcms2 >=2.17,<3.0a0 + - zlib-ng >=2.2.5,<2.3.0a0 - tk >=8.6.13,<8.7.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - libtiff >=4.7.1,<4.8.0a0 license: HPND purls: - pkg:pypi/pillow?source=hash-mapping - size: 41899294 - timestamp: 1746646850330 -- conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh145f28c_0.conda - sha256: e18efebe17b1cdef5bed19786c312c2f563981bbf8843490d5007311e448ff48 - md5: 01384ff1639c6330a0924791413b8714 + size: 943957 + timestamp: 1761655790641 +- conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda + sha256: 4d5e2faca810459724f11f78d19a0feee27a7be2b3fc5f7abbbec4c9fdcae93d + md5: bf47878473e5ab9fdb4115735230e191 depends: - python >=3.13.0a0 license: MIT license_family: MIT purls: - - pkg:pypi/pip?source=hash-mapping - size: 1244586 - timestamp: 1746250023993 + - pkg:pypi/pip?source=compressed-mapping + size: 1177084 + timestamp: 1762776338614 - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.8-unix_hf108a03_2.conda sha256: d61d62c0a7fa6ca17d9463d05a217040c621ca64b70a7afb4640e0ccfd63dec6 md5: 3b56ce640f2fdb4ea97f012ef924130e @@ -7720,28 +7947,18 @@ packages: purls: [] size: 6621 timestamp: 1750158524827 -- conda: https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_2.conda - sha256: adb2dde5b4f7da70ae81309cce6188ed3286ff280355cf1931b45d91164d2ad8 - md5: 5a5870a74432aa332f7d32180633ad05 +- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda + sha256: 7efd51b48d908de2d75cbb3c4a2e80dd9454e1c5bb8191b261af3136f7fa5888 + md5: 5c7a868f8241e64e1cf5fdf4962f23e2 depends: - - python >=3.9 - license: MIT AND PSF-2.0 - purls: - - pkg:pypi/pkgutil-resolve-name?source=hash-mapping - size: 10693 - timestamp: 1733344619659 -- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.8-pyhe01879c_0.conda - sha256: 0f48999a28019c329cd3f6fd2f01f09fc32cc832f7d6bbe38087ddac858feaa3 - md5: 424844562f5d337077b445ec6b1398a7 - depends: - - python >=3.9 + - python >=3.10 - python license: MIT license_family: MIT purls: - pkg:pypi/platformdirs?source=hash-mapping - size: 23531 - timestamp: 1746710438805 + size: 23625 + timestamp: 1759953252315 - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda sha256: a8eb555eef5063bbb7ba06a379fa7ea714f57d9741fe0efdb9442dbbc2cccbcc md5: 7da7ccd349dbf6487a7778579d2bb971 @@ -7750,7 +7967,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/pluggy?source=compressed-mapping + - pkg:pypi/pluggy?source=hash-mapping size: 24246 timestamp: 1747339794916 - pypi: ../eozilla/procodile @@ -7793,84 +8010,86 @@ packages: purls: [] size: 179103 timestamp: 1730769223221 -- conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.22.1-pyhd8ed1ab_0.conda - sha256: 454e2c0ef14accc888dd2cd2e8adb8c6a3a607d2d3c2f93962698b5718e6176d - md5: c64b77ccab10b822722904d889fa83b5 +- conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.23.1-pyhd8ed1ab_0.conda + sha256: 13dc67de68db151ff909f2c1d2486fa7e2d51355b25cee08d26ede1b62d48d40 + md5: a1e91db2d17fd258c64921cb38e6745a depends: - - python >=3.9 + - python >=3.10 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/prometheus-client?source=hash-mapping - size: 52641 - timestamp: 1748896836631 -- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - sha256: ebc1bb62ac612af6d40667da266ff723662394c0ca78935340a5b5c14831227b - md5: d17ae9db4dc594267181bd199bf9a551 + size: 54592 + timestamp: 1758278323953 +- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda + sha256: 4817651a276016f3838957bfdf963386438c70761e9faec7749d411635979bae + md5: edb16f14d920fb3faf17f5ce582942d6 depends: - - python >=3.9 + - python >=3.10 - wcwidth constrains: - - prompt_toolkit 3.0.51 + - prompt_toolkit 3.0.52 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/prompt-toolkit?source=hash-mapping - size: 271841 - timestamp: 1744724188108 -- conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - sha256: 936189f0373836c1c77cd2d6e71ba1e583e2d3920bf6d015e96ee2d729b5e543 - md5: 1e61ab85dd7c60e5e73d853ea035dc29 + size: 273927 + timestamp: 1756321848365 +- conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.52-hd8ed1ab_0.conda + sha256: e79922a360d7e620df978417dd033e66226e809961c3e659a193f978a75a9b0b + md5: 6d034d3a6093adbba7b24cb69c8c621e depends: - - prompt-toolkit >=3.0.51,<3.0.52.0a0 + - prompt-toolkit >=3.0.52,<3.0.53.0a0 license: BSD-3-Clause license_family: BSD - purls: - - pkg:pypi/prompt-toolkit?source=compressed-mapping - size: 7182 - timestamp: 1744724189376 -- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.0.0-py313h536fd9c_0.conda - sha256: 1b39f0ce5a345779d70c885664d77b5f8ef49f7378829bd7286a7fb98b7ea852 - md5: 8f315d1fce04a046c1b93fa6e536661d + purls: [] + size: 7212 + timestamp: 1756321849562 +- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.1.3-py313h54dd161_0.conda + sha256: 26cf5a69d04ef66f03516b8a8211a43bb23d5225faacd7d36e5c987b0d66af0a + md5: 1d719fc61f91ab2644a2eeb35fcab360 depends: + - python + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/psutil?source=hash-mapping - size: 475101 - timestamp: 1740663284505 -- conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.0.0-py313h63b0ddb_0.conda - sha256: b117f61eaf3d5fb640d773c3021f222c833a69c2ac123d7f4b028b3e5d638dd4 - md5: 2c8969aaee2cf24bc8931f5fc36cccfd + size: 501735 + timestamp: 1762092897061 +- conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.1.3-py313hcb05632_0.conda + sha256: 4ef3483cec1c30aaeb74356c855041d3b7d13ba7e835fa466cc4d5a7b5abf8f4 + md5: b2e3c688e2d87f25646125a6532a7a1b depends: + - python - __osx >=10.13 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/psutil?source=hash-mapping - size: 482494 - timestamp: 1740663492867 -- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.0.0-py313ha7868ed_0.conda - sha256: d8e5d86e939d5f308c7922835a94458afb29d81c90b5d43c43a5537c9c7adbc1 - md5: 3cdf99cf98b01856af9f26c5d8036353 + size: 512670 + timestamp: 1762092979899 +- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.1.3-py313h5fd188c_0.conda + sha256: 460ad6347bcd4d83533322af7e09b41347491f867142972cde24ea16c8d8680b + md5: d61d8550d0dfe99408532c33e7ec26b5 depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/psutil?source=hash-mapping - size: 491314 - timestamp: 1740663777370 + size: 520035 + timestamp: 1762092908165 - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda sha256: 9c88f8c64590e9567c6c80823f0328e58d3b1efb0e1c539c0315ceca764e0973 md5: b3c17d95b5a10c6e64a21fa17573e70e @@ -7925,62 +8144,63 @@ packages: - pkg:pypi/pure-eval?source=hash-mapping size: 16668 timestamp: 1733569518868 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-20.0.0-py313h78bf25f_0.conda - sha256: 61b27da2d9512f2c0ddad4a86725fa1d04f482b6bad374f3535d8bf21ea4b84e - md5: 6b8d388845ce750fe2ad8436669182f3 - depends: - - libarrow-acero 20.0.0.* - - libarrow-dataset 20.0.0.* - - libarrow-substrait 20.0.0.* - - libparquet 20.0.0.* - - pyarrow-core 20.0.0 *_0_* +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-22.0.0-py313h78bf25f_0.conda + sha256: 435ed4302740162c9ce21f1b36df7fcfab65095bf760f28f15901e8e67cd2a30 + md5: dfe7289ae9ad7aa091979a7c5e6a55c7 + depends: + - libarrow-acero 22.0.0.* + - libarrow-dataset 22.0.0.* + - libarrow-substrait 22.0.0.* + - libparquet 22.0.0.* + - pyarrow-core 22.0.0 *_0_* - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: Apache-2.0 license_family: APACHE purls: [] - size: 25773 - timestamp: 1746000973456 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-20.0.0-py313habf4b1d_0.conda - sha256: 27f7c4868ca64c7830afa528299796075dffef83bf10a562da02e3bd09592a62 - md5: ebe186e6a833cb685972cda875aa61dd - depends: - - libarrow-acero 20.0.0.* - - libarrow-dataset 20.0.0.* - - libarrow-substrait 20.0.0.* - - libparquet 20.0.0.* - - pyarrow-core 20.0.0 *_0_* + size: 26233 + timestamp: 1761648084519 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-22.0.0-py313habf4b1d_0.conda + sha256: 932ae171600148f23bfd35742637bc8f8e78f085d9165b05c139eb4204a03246 + md5: f5e7a81f8f1b2073bc4c149365a8f1d4 + depends: + - libarrow-acero 22.0.0.* + - libarrow-dataset 22.0.0.* + - libarrow-substrait 22.0.0.* + - libparquet 22.0.0.* + - pyarrow-core 22.0.0 *_0_* - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: Apache-2.0 license_family: APACHE purls: [] - size: 25866 - timestamp: 1746000544338 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-20.0.0-py313hfa70ccb_0.conda - sha256: 3be0426f579c47fffa51a9207079fceb8b81d7e6f523e1f0b66e96e7a5b13356 - md5: 8da637531c53d12fac29517798cde620 - depends: - - libarrow-acero 20.0.0.* - - libarrow-dataset 20.0.0.* - - libarrow-substrait 20.0.0.* - - libparquet 20.0.0.* - - pyarrow-core 20.0.0 *_0_* + size: 26262 + timestamp: 1761648441937 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-22.0.0-py313hfa70ccb_0.conda + sha256: 104875cb45452efb06c83e5233be86f1074fa3845d2d7735850128abb2a79058 + md5: dc9d22fa905cbb90914b29dc9791985d + depends: + - libarrow-acero 22.0.0.* + - libarrow-dataset 22.0.0.* + - libarrow-substrait 22.0.0.* + - libparquet 22.0.0.* + - pyarrow-core 22.0.0 *_0_* - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: Apache-2.0 license_family: APACHE purls: [] - size: 26278 - timestamp: 1746001244067 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-20.0.0-py313he5f92c8_0_cpu.conda - sha256: e65af8546ef38a398787964257b9af4706066a72501b9b781363a9c68a7b7e49 - md5: 2afdef63d9fbc2cd0e52f8e8f3472404 + size: 26695 + timestamp: 1761648693810 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-22.0.0-py313he109ebe_0_cpu.conda + sha256: 0be6da97fb9eaaa9768a997a933ed7461ff2a393a4ac68088f7bedd838c1c0f0 + md5: 0b4a0a9ab270b275eb6da8671edb9458 depends: - __glibc >=2.17,<3.0.a0 - - libarrow 20.0.0.* *cpu - - libgcc >=13 - - libstdcxx >=13 + - libarrow 22.0.0.* *cpu + - libarrow-compute 22.0.0.* *cpu + - libgcc >=14 + - libstdcxx >=14 - libzlib >=1.3.1,<2.0a0 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 @@ -7991,14 +8211,15 @@ packages: license_family: APACHE purls: - pkg:pypi/pyarrow?source=hash-mapping - size: 5216780 - timestamp: 1746000628209 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-core-20.0.0-py313hc71e1e6_0_cpu.conda - sha256: 644c8c32fb6b7ba4d8a6137a347dd43bbc48408288b1e9917fd81def61c82250 - md5: 57d00dac5fc3b9d9f6a63df7335ae37b + size: 5315561 + timestamp: 1761648066791 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-core-22.0.0-py313hff57800_0_cpu.conda + sha256: 8231efdf540a667dceefc429d7aa63b02f0dbf5d8f0f743308ac39733d1eddea + md5: 9685b1fb88da438a1151154c738d6840 depends: - __osx >=10.13 - - libarrow 20.0.0.* *cpu + - libarrow 22.0.0.* *cpu + - libarrow-compute 22.0.0.* *cpu - libcxx >=18 - libzlib >=1.3.1,<2.0a0 - python >=3.13,<3.14.0a0 @@ -8010,19 +8231,20 @@ packages: license_family: APACHE purls: - pkg:pypi/pyarrow?source=hash-mapping - size: 4473243 - timestamp: 1746000515633 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-core-20.0.0-py313he812468_0_cpu.conda - sha256: be8aa65282ab9d4f001ab908816011efe3c18adabe707a737b53c63d7f5e00dc - md5: a61d6de063ff8f4c3af7b62ae54ac2b5 - depends: - - libarrow 20.0.0.* *cpu + size: 4412888 + timestamp: 1761648393649 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-core-22.0.0-py313h5921983_0_cpu.conda + sha256: f8f2239baba1ca90da1714a08b4867597bc320df45a181bd857472708f3e0f0a + md5: ce1a640327f28325e345246fa838bd41 + depends: + - libarrow 22.0.0.* *cpu + - libarrow-compute 22.0.0.* *cpu - libzlib >=1.3.1,<2.0a0 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - apache-arrow-proc * cpu - numpy >=1.21,<3 @@ -8030,8 +8252,8 @@ packages: license_family: APACHE purls: - pkg:pypi/pyarrow?source=hash-mapping - size: 3461040 - timestamp: 1746000895380 + size: 3521330 + timestamp: 1761648321931 - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda sha256: 79db7928d13fab2d892592223d7570f5061c192f27b9febd1a418427b719acc6 md5: 12c566707c80111f9799308d9e265aef @@ -8044,29 +8266,29 @@ packages: - pkg:pypi/pycparser?source=hash-mapping size: 110100 timestamp: 1733195786147 -- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - sha256: ee7823e8bc227f804307169870905ce062531d36c1dcf3d431acd65c6e0bd674 - md5: 1b337e3d378cde62889bb735c024b7a2 +- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.4-pyh3cfb1c2_0.conda + sha256: c51297f0f6ef13776cc5b61c37d00c0d45faaed34f81d196e64bebc989f3e497 + md5: bf6ce72315b6759453d8c90a894e9e4c depends: - annotated-types >=0.6.0 - - pydantic-core 2.33.2 - - python >=3.9 + - pydantic-core 2.41.5 + - python >=3.10 - typing-extensions >=4.6.1 - - typing-inspection >=0.4.0 - - typing_extensions >=4.12.2 + - typing-inspection >=0.4.2 + - typing_extensions >=4.14.1 license: MIT license_family: MIT purls: - - pkg:pypi/pydantic?source=compressed-mapping - size: 307333 - timestamp: 1749927245525 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.33.2-py313h4b2b08d_0.conda - sha256: 754e3739e4b2a8856573e75829a1cccc0d16ee59dbee6ad594a70728a90e2854 - md5: 04b21004fe9316e29c92aa3accd528e5 + - pkg:pypi/pydantic?source=hash-mapping + size: 320446 + timestamp: 1762379584494 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.41.5-py313h843e2db_0.conda + sha256: ef873b022656313991ec6e07ad1708e64b7d712de896b1907bd091dfe453b1e0 + md5: b7ecbb230837ea4f4f60227dc8b491b7 depends: - python - typing-extensions >=4.6.0,!=4.7.0 - - libgcc >=13 + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - python_abi 3.13.* *_cp313 constrains: @@ -8075,11 +8297,11 @@ packages: license_family: MIT purls: - pkg:pypi/pydantic-core?source=hash-mapping - size: 1894157 - timestamp: 1746625309269 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.33.2-py313hb35714d_0.conda - sha256: 84b5d39c74f8578722b0fc40b6c0a862cff590549ff74abfe88210f98526fa62 - md5: d005389707c7f9ccc4f86933b4649708 + size: 1944972 + timestamp: 1762358832380 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.41.5-py313hcc225dc_0.conda + sha256: 7b200b234685a0b4d89ac42c0fcdc41ecbd5396a5940f878bfd223eaf624ba6d + md5: 0ad0de3b4c48fc12c036361347854b00 depends: - python - typing-extensions >=4.6.0,!=4.7.0 @@ -8091,27 +8313,27 @@ packages: license_family: MIT purls: - pkg:pypi/pydantic-core?source=hash-mapping - size: 1867059 - timestamp: 1746625317183 -- conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.33.2-py313ha8a9a3c_0.conda - sha256: 14dc654f3bb8e5a489da6632cf91b421a32e0d1c521d4f0b64a6910ae51d5c8f - md5: b3a8def3a1d2e94644e2a9c0b8717f4a + size: 1951438 + timestamp: 1762358861637 +- conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.41.5-py313hfbe8231_0.conda + sha256: 82ee80cb7272551031d7e8a42494ce3d67897288605bcb76269c995ea8aa69fc + md5: 639e9460fc15dce7b0eed455c84d6c8d depends: - python - typing-extensions >=4.6.0,!=4.7.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - python_abi 3.13.* *_cp313 license: MIT license_family: MIT purls: - pkg:pypi/pydantic-core?source=hash-mapping - size: 1905166 - timestamp: 1746625395940 + size: 1976270 + timestamp: 1762358914181 - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a md5: 6b6ece66ebcae2d5f326c77ef2c5a066 @@ -8120,12 +8342,12 @@ packages: license: BSD-2-Clause license_family: BSD purls: - - pkg:pypi/pygments?source=compressed-mapping + - pkg:pypi/pygments?source=hash-mapping size: 889287 timestamp: 1750615908735 -- conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16-pyhd8ed1ab_0.conda - sha256: 7465d67daa980999606138d74631563f5c233624cf5d65fc3f1f7210fce91b64 - md5: 79dbb1bfe734d8e8b36ca328a63fb4de +- conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda + sha256: 8f575f123694e5acd2829440da55828f2cea60b0af5d8fa5406d83251ba80f61 + md5: 26e013bc453e643991cfa9b76911fb79 depends: - markdown >=3.6 - python >=3.9 @@ -8134,14 +8356,14 @@ packages: license_family: MIT purls: - pkg:pypi/pymdown-extensions?source=hash-mapping - size: 171431 - timestamp: 1750571864207 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-core-11.1-py313h6971d95_0.conda - sha256: 17d1aeea68b091508e2bc8e58023788dcd7592143c909ede5b634d059d930f30 - md5: 6b77cb82a5311aa457295cec63adbbc8 + size: 170121 + timestamp: 1753743741894 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-core-12.0-py313h07bcf3a_2.conda + sha256: db216f3c43a955a056173eca2baa8ecbfa3fa3d67ecfbcdead9c90be031b560c + md5: 71fd34f70212d4e0cc435aa441148128 depends: - __osx >=10.13 - - libffi >=3.4.6,<3.5.0a0 + - libffi >=3.5.2,<3.6.0a0 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - setuptools @@ -8149,23 +8371,22 @@ packages: license_family: MIT purls: - pkg:pypi/pyobjc-core?source=hash-mapping - size: 488220 - timestamp: 1750207845515 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-framework-cocoa-11.1-py313h19a8f7f_0.conda - sha256: f370c937cf20d0ef198f9ce1870ed61e6384d0fe4e85a01853d866ba86eb58ab - md5: f9b008619c45d0381e0900912c4ff554 + size: 489967 + timestamp: 1762461057373 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-framework-cocoa-12.0-py313hf669bc3_2.conda + sha256: 0cdb787cde4290a325ca2316b0f1425af3c8e0f247c3d756b2466ff2065c9557 + md5: fd6f0c6b09d57a64fe46a6837e7f8737 depends: - __osx >=10.13 - - libffi >=3.4.6,<3.5.0a0 - - pyobjc-core 11.1.* + - libffi >=3.5.2,<3.6.0a0 + - pyobjc-core 12.0.* - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: MIT - license_family: MIT purls: - pkg:pypi/pyobjc-framework-cocoa?source=hash-mapping - size: 382930 - timestamp: 1750225358268 + size: 376036 + timestamp: 1762486176370 - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda sha256: d016e04b0e12063fbee4a2d5fbb9b39a8d191b5a0042f0b8459188aedeabb0ca md5: e2fd202833c4a981ce8a65974fe4abd1 @@ -8191,149 +8412,163 @@ packages: - pkg:pypi/pysocks?source=hash-mapping size: 21085 timestamp: 1733217331982 -- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.1-pyhd8ed1ab_0.conda - sha256: 93e267e4ec35353e81df707938a6527d5eb55c97bf54c3b87229b69523afb59d - md5: a49c2283f24696a7b30367b7346a0144 +- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.0-pyhcf101f3_0.conda + sha256: afd413cd919bd3cca1d45062b9822be8935e1f61ce6d6b2642364e8c19e2873d + md5: 499e8e2df95ad3d263bee8d41cc3d475 depends: - - colorama >=0.4 - - exceptiongroup >=1 - - iniconfig >=1 - - packaging >=20 - - pluggy >=1.5,<2 - pygments >=2.7.2 - - python >=3.9 + - python >=3.10 + - iniconfig >=1.0.1 + - packaging >=22 + - pluggy >=1.5,<2 - tomli >=1 + - colorama >=0.4 + - exceptiongroup >=1 + - python constrains: - pytest-faulthandler >=2 license: MIT - license_family: MIT purls: - pkg:pypi/pytest?source=hash-mapping - size: 276562 - timestamp: 1750239526127 -- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.2.1-pyhd8ed1ab_0.conda - sha256: 3a9fc07be76bc67aef355b78816b5117bfe686e7d8c6f28b45a1f89afe104761 - md5: ce978e1b9ed8b8d49164e90a5cdc94cd - depends: - - coverage >=7.5 - - pytest >=4.6 - - python >=3.9 - - toml + size: 298822 + timestamp: 1762632428892 +- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-7.0.0-pyhcf101f3_1.conda + sha256: d0f45586aad48ef604590188c33c83d76e4fc6370ac569ba0900906b24fd6a26 + md5: 6891acad5e136cb62a8c2ed2679d6528 + depends: + - coverage >=7.10.6 + - pluggy >=1.2 + - pytest >=7 + - python >=3.10 + - python license: MIT license_family: MIT purls: - - pkg:pypi/pytest-cov?source=compressed-mapping - size: 28216 - timestamp: 1749778064293 -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.5-hec9711d_102_cp313.conda - build_number: 102 - sha256: c2cdcc98ea3cbf78240624e4077e164dc9d5588eefb044b4097c3df54d24d504 - md5: 89e07d92cf50743886f41638d58c4328 + - pkg:pypi/pytest-cov?source=hash-mapping + size: 29016 + timestamp: 1757612051022 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda + build_number: 101 + sha256: e89da062abd0d3e76c8d3b35d3cafc5f0d05914339dcb238f9e3675f2a58d883 + md5: 4780fe896e961722d0623fa91d0d3378 depends: - __glibc >=2.17,<3.0.a0 - bzip2 >=1.0.8,<2.0a0 - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.7.0,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 - - libgcc >=13 + - libexpat >=2.7.1,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.50.1,<4.0a0 - - libuuid >=2.38.1,<3.0a0 + - libsqlite >=3.50.4,<4.0a0 + - libuuid >=2.41.2,<3.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.5.0,<4.0a0 + - openssl >=3.5.4,<4.0a0 - python_abi 3.13.* *_cp313 - readline >=8.2,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata license: Python-2.0 purls: [] - size: 33273132 - timestamp: 1750064035176 + size: 37174029 + timestamp: 1761178179147 python_site_packages_path: lib/python3.13/site-packages -- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.5-hc3a4c56_102_cp313.conda - build_number: 102 - sha256: 8b2f14010eb0baf04ed1eb3908c9e184cd14512c4d64c43f313251b90e75b345 - md5: afa9492a7d31f6f7189ca8f08aceadac +- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.9-h17c18a5_101_cp313.conda + build_number: 101 + sha256: b56484229cf83f6c84e8b138dc53f7f2fa9ee850f42bf1f6d6fa1c03c044c2d3 + md5: fb1e51574ce30d2a4d5e4facb9b2cbd5 depends: - __osx >=10.13 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.0,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 + - libexpat >=2.7.1,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.50.1,<4.0a0 + - libsqlite >=3.50.4,<4.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.5.0,<4.0a0 + - openssl >=3.5.4,<4.0a0 - python_abi 3.13.* *_cp313 - readline >=8.2,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata license: Python-2.0 purls: [] - size: 13955531 - timestamp: 1750063132430 + size: 17521522 + timestamp: 1761177097697 python_site_packages_path: lib/python3.13/site-packages -- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.5-h7de537c_102_cp313.conda - build_number: 102 - sha256: 3de2b9f89b220cb779f6947cf87b328f73d54eed4f7e75a3f9337caeb4443910 - md5: a9a4658f751155c819d6cd4c47f0a4d2 +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.9-h09917c8_101_cp313.conda + build_number: 101 + sha256: bc855b513197637c2083988d5cbdcc407a23151cdecff381bd677df33d516a01 + md5: 89d992b9d4b9e88ed54346c9c4a24c1c depends: - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.0,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 + - libexpat >=2.7.1,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.50.1,<4.0a0 + - libsqlite >=3.50.4,<4.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 + - openssl >=3.5.4,<4.0a0 - python_abi 3.13.* *_cp313 - tk >=8.6.13,<8.7.0a0 - tzdata - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Python-2.0 purls: [] - size: 16825621 - timestamp: 1750062318985 + size: 16613183 + timestamp: 1761175050438 python_site_packages_path: Lib/site-packages -- conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda - sha256: a50052536f1ef8516ed11a844f9413661829aa083304dc624c5925298d078d79 - md5: 5ba79d7c71f03c678c8ead841f347d6e +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + sha256: d6a17ece93bbd5139e02d2bd7dbfa80bee1a4261dced63f65f679121686bf664 + md5: 5b8d21249ff20967101ffa321cab24e8 depends: - python >=3.9 - six >=1.5 + - python license: Apache-2.0 license_family: APACHE purls: - pkg:pypi/python-dateutil?source=hash-mapping - size: 222505 - timestamp: 1733215763718 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.1.1-pyhe01879c_0.conda - sha256: 9a90570085bedf4c6514bcd575456652c47918ff3d7b383349e26192a4805cc8 - md5: a245b3c04afa11e2e52a0db91550da7c + size: 233310 + timestamp: 1751104122689 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.1-pyhcf101f3_0.conda + sha256: aa98e0b1f5472161318f93224f1cfec1355ff69d2f79f896c0b9e033e4a6caf9 + md5: 083725d6cd3dc007f06d04bcf1e613a2 depends: - - python >=3.9 + - python >=3.10 - python license: BSD-3-Clause + license_family: BSD purls: - pkg:pypi/python-dotenv?source=hash-mapping - size: 26031 - timestamp: 1750789290754 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.1-pyhd8ed1ab_0.conda - sha256: 1b09a28093071c1874862422696429d0d35bd0b8420698003ac004746c5e82a2 - md5: 38e34d2d1d9dca4fb2b9a0a04f604e2c + size: 26922 + timestamp: 1761503229008 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + sha256: df9aa74e9e28e8d1309274648aac08ec447a92512c33f61a8de0afa9ce32ebe8 + md5: 23029aae904a2ba587daba708208012f depends: - python >=3.9 + - python license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/fastjsonschema?source=hash-mapping - size: 226259 - timestamp: 1733236073335 + size: 244628 + timestamp: 1755304154927 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.9-h4df99d1_101.conda + sha256: 7535b9cb2414e34c73ed4a97a90bcadcc76b9d47d0bb8ef5002c592d85fe022d + md5: f41e3c1125e292e6bfcea8392a3de3d8 + depends: + - cpython 3.13.9.* + - python_abi * *_cp313 + license: Python-2.0 + purls: [] + size: 48385 + timestamp: 1761175154112 - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda sha256: 4790787fe1f4e8da616edca4acf6a4f8ed4e7c6967aa31b920208fc8f95efcca md5: a61bf9ec79426938ff785eb69dbb1960 @@ -8364,20 +8599,20 @@ packages: license: Apache-2.0 license_family: APACHE purls: - - pkg:pypi/tzdata?source=compressed-mapping + - pkg:pypi/tzdata?source=hash-mapping size: 144160 timestamp: 1742745254292 -- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-7_cp313.conda - build_number: 7 - sha256: 0595134584589064f56e67d3de1d8fcbb673a972946bce25fb593fb092fdcd97 - md5: e84b44e6300f1703cb25d29120c5b1d8 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + build_number: 8 + sha256: 210bffe7b121e651419cb196a2a63687b087497595c9be9d20ebe97dd06060a7 + md5: 94305520c52a4aa3f6c2b1ff6008d9f8 constrains: - python 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: [] - size: 6988 - timestamp: 1745258852285 + size: 7002 + timestamp: 1752805902938 - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda sha256: 8d2a8bf110cc1fc3df6904091dead158ba3e614d8402a83e51ed3a8aa93cdeb0 md5: bc8e3267d44011051f2eb14d22fb0960 @@ -8403,36 +8638,39 @@ packages: - pkg:pypi/pyviz-comms?source=hash-mapping size: 49425 timestamp: 1750669964512 -- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-307-py313h5813708_3.conda - sha256: 0a68b324ea47ae720c62522c5d0bb5ea3e4987e1c5870d6490c7f954fbe14cbe - md5: 7113bd6cfe34e80d8211f7c019d14357 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda + sha256: 87eaeb79b5961e0f216aa840bc35d5f0b9b123acffaecc4fda4de48891901f20 + md5: 1ce4f826332dca56c76a5b0cc89fb19e depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 license: PSF-2.0 license_family: PSF purls: - pkg:pypi/pywin32?source=hash-mapping - size: 6060096 - timestamp: 1728636763526 -- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-ctypes-0.2.3-py313hfa70ccb_1.conda - sha256: 4552b2a4a53caaf06c4abc8142981ffac070941708faee40706ae26477281ce7 - md5: c838b4e201fc7a40ce746286efb1c3a3 + size: 6695114 + timestamp: 1756487139550 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-ctypes-0.2.3-py313hfa70ccb_3.conda + sha256: dec893227662cf003f161d5a80af8d01d4a21c772737768c0d2d56ed67819473 + md5: 21a8bad6a2c8e821379595ad48577c23 depends: - - python >=3.13.0rc2,<3.14.0a0 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/pywin32-ctypes?source=hash-mapping - size: 57565 - timestamp: 1727282366649 -- conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_0.conda - sha256: 4210038442e3f34d67de9aeab2691fa2a6f80dc8c16ab77d5ecbb2b756e04ff0 - md5: cd1fadcdf82a423c2441a95435eeab3c + size: 57717 + timestamp: 1762489947867 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda + sha256: d34a7cd0a4a7dc79662cb6005e01d630245d9a942e359eb4d94b2fb464ed2552 + md5: 8f01ed27e2baa455e753301218e054fd depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 @@ -8444,26 +8682,26 @@ packages: license_family: MIT purls: - pkg:pypi/pywinpty?source=hash-mapping - size: 217133 - timestamp: 1738661059040 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.2-py313h8060acc_2.conda - sha256: 6826217690cfe92d6d49cdeedb6d63ab32f51107105d6a459d30052a467037a0 - md5: 50992ba61a8a1f8c2d346168ae1c86df + size: 216075 + timestamp: 1759556799508 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_0.conda + sha256: 40dcd6718dce5fbee8aabdd0519f23d456d8feb2e15ac352eaa88bbfd3a881af + md5: 4794ea0adaebd9f844414e594b142cb2 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - yaml >=0.2.5,<0.3.0a0 license: MIT license_family: MIT purls: - - pkg:pypi/pyyaml?source=hash-mapping - size: 205919 - timestamp: 1737454783637 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.2-py313h717bdf5_2.conda - sha256: 27501e9b3b5c6bfabb3068189fd40c650356a258e4a82b0cfe31c60f568dcb85 - md5: b7f2984724531d2233b77c89c54be594 + - pkg:pypi/pyyaml?source=compressed-mapping + size: 207109 + timestamp: 1758892173548 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.3-py313h0f4d31d_0.conda + sha256: 8420815e10d455b012db39cb7dc0d86f0ac3a287d5a227892fa611fe3d467df9 + md5: e0c9e257970870212c449106964a5ace depends: - __osx >=10.13 - python >=3.13,<3.14.0a0 @@ -8473,24 +8711,24 @@ packages: license_family: MIT purls: - pkg:pypi/pyyaml?source=hash-mapping - size: 196573 - timestamp: 1737455046063 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.2-py313hb4c8b1a_2.conda - sha256: 5b496c96e48f495de41525cb1b603d0147f2079f88a8cf061aaf9e17a2fe1992 - md5: d14f685b5d204b023c641b188a8d0d7c + size: 193608 + timestamp: 1758892017635 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_0.conda + sha256: 5d9fd32d318b9da615524589a372b33a6f3d07db2708de16570d70360bf638c2 + md5: c067122d76f8dcbe0848822942ba07be depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - yaml >=0.2.5,<0.3.0a0 license: MIT license_family: MIT purls: - - pkg:pypi/pyyaml?source=hash-mapping - size: 182783 - timestamp: 1737455202579 + - pkg:pypi/pyyaml?source=compressed-mapping + size: 182043 + timestamp: 1758892011955 - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-env-tag-1.1-pyhd8ed1ab_0.conda sha256: 69ab63bd45587406ae911811fc4d4c1bf972d643fa57a009de7c01ac978c4edd md5: e8e53c4150a1bba3b160eacf9d53a51b @@ -8503,86 +8741,92 @@ packages: - pkg:pypi/pyyaml-env-tag?source=hash-mapping size: 11137 timestamp: 1747237061448 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.0.0-py313h8e95178_0.conda - sha256: 6446721c43ba540c02ced4dde564f5a9a0131e40aa406e8af6313084c4a2024f - md5: c912a00e5cb59357ef55b7930a48cf48 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hfb55c3c_0.conda + noarch: python + sha256: a00a41b66c12d9c60e66b391e9a4832b7e28743348cf4b48b410b91927cd7819 + md5: 3399d43f564c905250c1aea268ebb935 depends: + - python - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libsodium >=1.0.20,<1.0.21.0a0 - - libstdcxx >=13 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - libstdcxx >=14 + - libgcc >=14 + - _python_abi3_support 1.* + - cpython >=3.12 - zeromq >=4.3.5,<4.4.0a0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/pyzmq?source=hash-mapping - size: 384549 - timestamp: 1749898593849 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pyzmq-27.0.0-py313h2d45800_0.conda - sha256: a97ec0b43ec20c6730dd4765d033eeef7370364467190899aa554db1be4cff02 - md5: 0dfe209a2803bf6c87f2bdbe92697c31 + size: 212218 + timestamp: 1757387023399 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pyzmq-27.1.0-py312hb7d603e_0.conda + noarch: python + sha256: 4e052fa3c4ed319e7bcc441fca09dee4ee4006ac6eb3d036a8d683fceda9304b + md5: 81511d0be03be793c622c408c909d6f9 depends: + - python - __osx >=10.13 - - libcxx >=18 - - libsodium >=1.0.20,<1.0.21.0a0 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - libcxx >=19 + - _python_abi3_support 1.* + - cpython >=3.12 - zeromq >=4.3.5,<4.4.0a0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/pyzmq?source=hash-mapping - size: 369843 - timestamp: 1749898684229 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.0.0-py313h2100fd5_0.conda - sha256: a5c2b81169250a6a6d292395c9f54aec3f13f6388b6c7b88d69451e96b2402bc - md5: 4db98bb029ca5432eb1c2ddbff5837a9 + size: 191697 + timestamp: 1757387104297 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312hbb5da91_0.conda + noarch: python + sha256: fd46b30e6a1e4c129045e3174446de3ca90da917a595037d28595532ab915c5d + md5: 808d263ec97bbd93b41ca01552b5fbd4 depends: - - libsodium >=1.0.20,<1.0.21.0a0 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - zeromq >=4.3.5,<4.3.6.0a0 + - _python_abi3_support 1.* + - cpython >=3.12 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/pyzmq?source=hash-mapping - size: 370348 - timestamp: 1749898835643 -- conda: https://conda.anaconda.org/conda-forge/linux-64/re2-2024.07.02-h9925aae_3.conda - sha256: 66d34e3b4881f856486d11914392c585713100ca547ccfc0947f3a4765c2c486 - md5: 6f445fb139c356f903746b2b91bbe786 + size: 185711 + timestamp: 1757387025899 +- conda: https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_0.conda + sha256: 2f225ddf4a274743045aded48053af65c31721e797a45beed6774fdc783febfb + md5: 0227d04521bc3d28c7995c7e1f99a721 depends: - - libre2-11 2024.07.02 hba17884_3 + - libre2-11 2025.11.05 h7b12aa8_0 license: BSD-3-Clause license_family: BSD purls: [] - size: 26811 - timestamp: 1741121137599 -- conda: https://conda.anaconda.org/conda-forge/osx-64/re2-2024.07.02-hf8a452e_3.conda - sha256: 291ebc1f3c6d479077399298c42c5e510e354664212cba74c04b9ab13ad811de - md5: 11dae9af12311eee952f3431282c822d + size: 27316 + timestamp: 1762397780316 +- conda: https://conda.anaconda.org/conda-forge/osx-64/re2-2025.11.05-h7df6414_0.conda + sha256: cd892b6b571fc6aaf9132a859e5ef0fae9e9ff980337ce7284798fa1d24bee5d + md5: 13dc8eedbaa30b753546e3d716f51816 depends: - - libre2-11 2024.07.02 h08ce7b7_3 + - libre2-11 2025.11.05 h554ac88_0 license: BSD-3-Clause license_family: BSD purls: [] - size: 26925 - timestamp: 1741121237531 -- conda: https://conda.anaconda.org/conda-forge/win-64/re2-2024.07.02-haf4117d_3.conda - sha256: d67e5d4b934f6ab9d50504584f672062bc5363f15a587b52d7c827611d0dbf44 - md5: f94cfa965a6498540057555957903dba + size: 27381 + timestamp: 1762398153069 +- conda: https://conda.anaconda.org/conda-forge/win-64/re2-2025.11.05-ha104f34_0.conda + sha256: 9d1bb3d15cdd3257baee5fc063221514482f91154cd1457af126e1ec460bbeac + md5: 50746f61f199c4c00d42e33f5d6cfd0b depends: - - libre2-11 2024.07.02 hd248061_3 + - libre2-11 2025.11.05 h0eb2380_0 license: BSD-3-Clause license_family: BSD purls: [] - size: 220297 - timestamp: 1741121702233 + size: 216623 + timestamp: 1762397986736 - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda sha256: 2d6d0c026902561ed77cd646b5021aef2d4db22e57a5b0178dfc669231e06d2c md5: 283b96675859b20a825f8fa30f311446 @@ -8604,12 +8848,12 @@ packages: purls: [] size: 256712 timestamp: 1740379577668 -- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.36.2-pyh29332c3_0.conda - sha256: e20909f474a6cece176dfc0dc1addac265deb5fa92ea90e975fbca48085b20c3 - md5: 9140f1c09dd5489549c6a33931b943c7 +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 + md5: 870293df500ca7e18bedefa5838a22ab depends: - attrs >=22.2.0 - - python >=3.9 + - python >=3.10 - rpds-py >=0.7.0 - typing_extensions >=4.4.0 - python @@ -8617,11 +8861,11 @@ packages: license_family: MIT purls: - pkg:pypi/referencing?source=hash-mapping - size: 51668 - timestamp: 1737836872415 -- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.4-pyhd8ed1ab_0.conda - sha256: 9866aaf7a13c6cfbe665ec7b330647a0fb10a81e6f9b8fee33642232a1920e18 - md5: f6082eae112814f1447b56a5e1f6ed05 + size: 51788 + timestamp: 1760379115194 +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda + sha256: 8dc54e94721e9ab545d7234aa5192b74102263d3e704e6d0c8aa7008f2da2a7b + md5: db0c6b99149880c8ba515cf4abe93ee4 depends: - certifi >=2017.4.17 - charset-normalizer >=2,<4 @@ -8634,8 +8878,8 @@ packages: license_family: APACHE purls: - pkg:pypi/requests?source=hash-mapping - size: 59407 - timestamp: 1749498221996 + size: 59263 + timestamp: 1755614348400 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda sha256: 2e4372f600490a6e0b3bac60717278448e323cab1c0fecd5f43f7c56535a99c5 md5: 36de09a8d3e5d5e6f4ee63af49e59706 @@ -8659,26 +8903,39 @@ packages: - pkg:pypi/rfc3986-validator?source=hash-mapping size: 7818 timestamp: 1598024297745 -- conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.0.0-pyh29332c3_0.conda - sha256: d10e2b66a557ec6296844e04686db87818b0df87d73c06388f2332fda3f7d2d5 - md5: 202f08242192ce3ed8bdb439ba40c0fe +- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + sha256: 70001ac24ee62058557783d9c5a7bbcfd97bd4911ef5440e3f7a576f9e43bc92 + md5: 7234f99325263a5af6d4cd195035e8f2 + depends: + - python >=3.9 + - lark >=1.2.2 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/rfc3987-syntax?source=hash-mapping + size: 22913 + timestamp: 1752876729969 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda + sha256: edfb44d0b6468a8dfced728534c755101f06f1a9870a7ad329ec51389f16b086 + md5: a247579d8a59931091b16a1e932bbed6 depends: - markdown-it-py >=2.2.0 - pygments >=2.13.0,<3.0.0 - - python >=3.9 + - python >=3.10 - typing_extensions >=4.0.0,<5.0.0 - python license: MIT license_family: MIT purls: - - pkg:pypi/rich?source=hash-mapping - size: 200323 - timestamp: 1743371105291 -- conda: https://conda.anaconda.org/conda-forge/noarch/rich-toolkit-0.11.3-pyh29332c3_0.conda - sha256: e558f8c254a9ff9164d069110da162fc79497d70c60f2c09a5d3d0d7101c5628 - md5: 4ba15ae9388b67d09782798347481f69 + - pkg:pypi/rich?source=compressed-mapping + size: 200840 + timestamp: 1760026188268 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-toolkit-0.15.1-pyhcf101f3_0.conda + sha256: 7c8ffaa40bf4ba5fc6bb8f0e4b9da77678fe74cdb50ab82041d6a5e4a25f530b + md5: 12f69ed6e4115871451a3c7809b4651e depends: - - python >=3.9 + - python >=3.10 - rich >=13.7.1 - click >=8.1.7 - typing_extensions >=4.12.2 @@ -8687,14 +8944,14 @@ packages: license_family: MIT purls: - pkg:pypi/rich-toolkit?source=hash-mapping - size: 17357 - timestamp: 1733750834072 -- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.25.1-py313h4b2b08d_0.conda - sha256: 2efdf436726331563221b41413cfa580df960c929f0e75619775cda880d59bd3 - md5: 109d190262b861bb608b7c977c6971ff + size: 29432 + timestamp: 1756998936181 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.28.0-py313h843e2db_1.conda + sha256: d0bcf40c20b4c4921b0c244b2ae1a9188f511cdeff5974602900257d7aa2ee0c + md5: b4e5c52948b191bfb04da5788217afdb depends: - python - - libgcc >=13 + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - python_abi 3.13.* *_cp313 constrains: @@ -8703,11 +8960,11 @@ packages: license_family: MIT purls: - pkg:pypi/rpds-py?source=hash-mapping - size: 391302 - timestamp: 1747837838085 -- conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.25.1-py313hb35714d_0.conda - sha256: 318f65abb743ee3f80e9b74bf0aee8f69134d9b97c218fc0c3ba8e9b07d8f170 - md5: c99c56b5536b1e367c57acd7a88082f9 + size: 380486 + timestamp: 1761178917553 +- conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.28.0-py313hcc225dc_1.conda + sha256: 5b6c6579188626f0a9d392218c72b6608739542192f8288b6f66c53fccbb4913 + md5: 3d246461e113f0dc3e992f256dda09a0 depends: - python - __osx >=10.13 @@ -8718,145 +8975,114 @@ packages: license_family: MIT purls: - pkg:pypi/rpds-py?source=hash-mapping - size: 370871 - timestamp: 1747837744984 -- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.25.1-py313ha8a9a3c_0.conda - sha256: f9a4e4e57fb6b6f82a70f533edc5b2be1084770b6cd99913713ab856886da7d9 - md5: 16d91b61a62fa344b9c1200b13925fbd + size: 366957 + timestamp: 1761178597606 +- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.28.0-py313hfbe8231_1.conda + sha256: 98a042a41e9c14b3500b560d3cc83ad4d05180dc1bbfadb9e416826016b4649e + md5: b78312a5f81f1a7f20cabc5efe5b15ce depends: - python - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - python_abi 3.13.* *_cp313 license: MIT license_family: MIT purls: - pkg:pypi/rpds-py?source=hash-mapping - size: 252641 - timestamp: 1747837734433 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.12.0-py313h67f39b2_0.conda - sha256: cff1e8f86787f8f817c781d95bebe251586868e273456f0b3d7d61dfac906942 - md5: 183f45c30ca7db594a4a66cee2f9ab4a + size: 240192 + timestamp: 1761178419906 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.14.4-h813ae00_0.conda + noarch: python + sha256: 23121b3e5d6f0cfe8cf6600a2b1e63e4f8cdd3aa2ceee25625b98a3caa2d93e5 + md5: a62b7614fdd1b448700d7e4078cc1b28 depends: + - python + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 constrains: - __glibc >=2.17 license: MIT - license_family: MIT purls: - pkg:pypi/ruff?source=hash-mapping - size: 8294729 - timestamp: 1750188351898 -- conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.12.0-py313h1aad41e_0.conda - sha256: b3f63a0b340a0e62cc0c7db276ccf7af97bd5c9754667fcac9501feeb1bf7693 - md5: 59013e2529ccc91f0dad6b14883155f6 + size: 11120550 + timestamp: 1762483239399 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.14.4-hd9f4cfa_0.conda + noarch: python + sha256: 2ade81fdcb134cb2966f630b89d00d1ef815f45699dd1246d4275f83d0e667df + md5: 104942f153208b01915d51ea8537d753 depends: - - __osx >=10.13 - - libcxx >=18 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python + - __osx >=10.13 constrains: - __osx >=10.13 license: MIT - license_family: MIT purls: - pkg:pypi/ruff?source=hash-mapping - size: 7925061 - timestamp: 1750188632324 -- conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.12.0-py313h784dc11_0.conda - sha256: dcbf3bced2d3d42067b9ae27b6d81333b3a2626e923a0b4d8943f0537a6eda3e - md5: 584dcc5cc9b423bd774ff5660dc7e6f8 + size: 10975891 + timestamp: 1762483351302 +- conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.14.4-h15e3a1f_0.conda + noarch: python + sha256: 16c4afd851c3ced17ac6b5308b5434b26032f55d700ab202e701c8bfa286f52f + md5: fbd57518cd61e83e5bafa8ac24f12358 depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 license: MIT - license_family: MIT purls: - - pkg:pypi/ruff?source=hash-mapping - size: 8291919 - timestamp: 1750189141795 -- pypi: ./s2gos-app-ex - name: s2gos-app-ex - version: 0.0.0 - sha256: fe053f016670ef03d9da693a3bfc9b912ad8dcb5dfe429ca625ffd59a768cc7d - requires_python: '>=3.10' - editable: true + - pkg:pypi/ruff?source=compressed-mapping + size: 11583754 + timestamp: 1762483250576 - pypi: ./s2gos-client name: s2gos-client - version: 0.0.6.dev0 - sha256: 6d6090cfc42bd9ee1a015f10dc18f9643b61adeb3f07ad95f0de26bc66098ef6 - requires_dist: - - click - - pydantic - - pyyaml - - typer - - uri-template - - httpx - - cuiman - - gavicore - requires_python: '>=3.10' - editable: true -- pypi: ./s2gos-common - name: s2gos-common - version: 0.0.6.dev0 - sha256: 29bba461bdf0b50cf903ce0ef2cc318161518bd025e70f97d98203eb1fd92a88 + version: 0.1.0.dev0 + sha256: 169c3f4b20de4b2267e655681771927382285c53a4b4cc92bea887965d0df1d3 requires_dist: - - pydantic - - typer + - cuiman>=0.0.8 + - gavicore>=0.0.8 requires_python: '>=3.10' editable: true - pypi: ./s2gos-server name: s2gos-server - version: 0.0.6.dev0 - sha256: 9689e8151fb46e2444a32f0e404c1bee19fd4ea5b4fe9e45ee1b72e3c60073b8 + version: 0.1.0.dev0 + sha256: f4c7000a30dba249ffdc11683ec6b64b912eb0d59aa5225ff5e497a5532e431f requires_dist: - - fastapi - - pydantic - - pyyaml - - typer - - uvicorn - - gavicore - - wraptile + - gavicore>=0.0.8 + - wraptile>=0.0.8 requires_python: '>=3.10' editable: true -- conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.21-h7ab7c64_0.conda - sha256: c8b252398b502a5cc6ea506fd2fafe7e102e7c9e2ef48b7813566e8a72ce2205 - md5: 28b5a7895024a754249b2ad7de372faa +- conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.6.0-h8399546_1.conda + sha256: f5b294ce9b40d15a4bc31b315364459c0d702dd3e8751fe8735c88ac6a9ddc67 + md5: 8dbc626b1b11e7feb40a14498567b954 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - openssl >=3.5.0,<4.0a0 + - libgcc >=14 + - openssl >=3.5.4,<4.0a0 license: Apache-2.0 license_family: Apache purls: [] - size: 358164 - timestamp: 1749095480268 -- conda: https://conda.anaconda.org/conda-forge/linux-64/secretstorage-3.3.3-py313h78bf25f_3.conda - sha256: 7f548e147e14ce743a796aa5f26aba11f82c14ab53ab25b48f35974ca48f6ac7 - md5: 813e01c086f6c4e134e13ef25b02df8c + size: 393615 + timestamp: 1762176592236 +- conda: https://conda.anaconda.org/conda-forge/linux-64/secretstorage-3.4.0-py313h78bf25f_0.conda + sha256: 6b4a6093963291fd0703eca97078107fc3024d744d3bf175aa6fc2af99a1eae1 + md5: 97dc269920a6ad86fe3e460d3b6663e3 depends: - - cryptography + - cryptography >=2.0 - dbus - jeepney >=0.6 - - python >=3.13.0rc1,<3.14.0a0 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/secretstorage?source=hash-mapping - size: 32074 - timestamp: 1725915738039 + size: 32835 + timestamp: 1757606804014 - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh0d859eb_1.conda sha256: 00926652bbb8924e265caefdb1db100f86a479e8f1066efe395d5552dde54d02 md5: 938c8de6b9de091997145b3bf25cdbf9 @@ -8906,63 +9132,67 @@ packages: - pkg:pypi/setuptools?source=hash-mapping size: 748788 timestamp: 1748804951958 -- conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_1.conda - sha256: 0557c090913aa63cdbe821dbdfa038a321b488e22bc80196c4b3b1aace4914ef - md5: 7c3c2a0f3ebdea2bbc35538d162b43bf +- conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_2.conda + sha256: 1d6534df8e7924d9087bd388fbac5bd868c5bf8971c36885f9f016da0657d22b + md5: 83ea3a2ddb7a75c1b09cea582aa4f106 depends: - - python >=3.9 + - python >=3.10 license: MIT - license_family: MIT purls: - pkg:pypi/shellingham?source=compressed-mapping - size: 14462 - timestamp: 1733301007770 -- conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda - sha256: 41db0180680cc67c3fa76544ffd48d6a5679d96f4b71d7498a759e94edc9a2db - md5: a451d576819089b0d672f18768be0f65 + size: 15018 + timestamp: 1762858315311 +- conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + sha256: 458227f759d5e3fcec5d9b7acce54e10c9e1f4f4b7ec978f3bfd54ce4ee9853d + md5: 3339e3b65d58accf4ca4fb8748ab16b3 depends: - python >=3.9 + - python license: MIT license_family: MIT purls: - pkg:pypi/six?source=hash-mapping - size: 16385 - timestamp: 1733381032766 -- conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.1-h8bd8927_1.conda - sha256: ec91e86eeb2c6bbf09d51351b851e945185d70661d2ada67204c9a6419d282d3 - md5: 3b3e64af585eadfb52bb90b553db5edf + size: 18455 + timestamp: 1753199211006 +- conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_0.conda + sha256: 8b8acbde6814d1643da509e11afeb6bb30eb1e3004cf04a7c9ae43e9b097f063 + md5: 3d8da0248bdae970b4ade636a104b7f5 depends: + - libgcc >=14 + - libstdcxx >=14 + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 license: BSD-3-Clause license_family: BSD purls: [] - size: 42739 - timestamp: 1733501881851 -- conda: https://conda.anaconda.org/conda-forge/osx-64/snappy-1.2.1-haf3c120_1.conda - sha256: 26e8a2edd2a12618d9adcdcfc6cfd9adaca8da71aa334615d29e803d225b52be - md5: 9d6ae6d5232233e1a01eb7db524078fb + size: 45805 + timestamp: 1753083455352 +- conda: https://conda.anaconda.org/conda-forge/osx-64/snappy-1.2.2-h25c286d_0.conda + sha256: e9ccbdbfaa9abd21636decd524d9845dee5a67af593b1d54525a48f2b03d3d76 + md5: e6544ab8824f58ca155a5b8225f0c780 depends: + - libcxx >=19 - __osx >=10.13 - - libcxx >=18 license: BSD-3-Clause license_family: BSD purls: [] - size: 36813 - timestamp: 1733502097580 -- conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.1-h500f7fa_1.conda - sha256: 29753b51803c0396c3cb56e4f11e68c968a2f43b71b648634bef1f9193f9e78b - md5: e32fb978aaea855ddce624eb8c8eb69a + size: 39975 + timestamp: 1753083485577 +- conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_0.conda + sha256: b38ed597bf71f73275a192b8cb22888997760bac826321f5838951d5d31acb23 + md5: 194a0c548899fa2a10684c34e56a3564 depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 license: BSD-3-Clause license_family: BSD purls: [] - size: 59757 - timestamp: 1733502109991 + size: 67221 + timestamp: 1753083479147 - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_1.conda sha256: c2248418c310bdd1719b186796ae50a8a77ce555228b6acd32768e2543a15012 md5: bf7a226e58dfb8346c70df36065d86c9 @@ -8985,17 +9215,17 @@ packages: - pkg:pypi/sortedcontainers?source=hash-mapping size: 28657 timestamp: 1738440459037 -- conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.7-pyhd8ed1ab_0.conda - sha256: 7518506cce9a736042132f307b3f4abce63bf076f5fb07c1f4e506c0b214295a - md5: fb32097c717486aa34b38a9db57eb49e +- conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda + sha256: c978576cf9366ba576349b93be1cfd9311c00537622a2f9e14ba2b90c97cae9c + md5: 18c019ccf43769d211f2cf78e9ad46c2 depends: - - python >=3.9 + - python >=3.10 license: MIT license_family: MIT purls: - pkg:pypi/soupsieve?source=hash-mapping - size: 37773 - timestamp: 1746563720271 + size: 37803 + timestamp: 1756330614547 - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda sha256: 570da295d421661af487f1595045760526964f41471021056e993e73089e9c41 md5: b1b505328da7a6b246787df4b5a49fbc @@ -9010,44 +9240,43 @@ packages: - pkg:pypi/stack-data?source=hash-mapping size: 26988 timestamp: 1733569565672 -- conda: https://conda.anaconda.org/conda-forge/noarch/starlette-0.46.2-pyh81abbef_0.conda - sha256: d41b9b2719a2a0176930df21d7fec7b758058e7fafd53dc900b5706cd627fa3a - md5: 36ec80c2b37e52760ab41be7c2bd1fd3 +- conda: https://conda.anaconda.org/conda-forge/noarch/starlette-0.49.2-pyhfdc7a7d_0.conda + sha256: 034f5356975f0e9013409d965ed8fa078cebf4955740a40bb859e4c321f6d823 + md5: 00e84fd6b7c38a785300ee5f699dc81b depends: - anyio >=3.6.2,<5 - - python >=3.9 - - typing_extensions >=3.10.0 + - python >=3.10 + - typing_extensions >=4.10.0 - python license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/starlette?source=hash-mapping - size: 62335 - timestamp: 1744661396275 -- conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.13.0-h62715c5_1.conda - sha256: 03cc5442046485b03dd1120d0f49d35a7e522930a2ab82f275e938e17b07b302 - md5: 9190dd0a23d925f7602f9628b3aed511 + - pkg:pypi/starlette?source=compressed-mapping + size: 64648 + timestamp: 1762002868324 +- conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-hd094cb3_1.conda + sha256: c31cac57913a699745d124cdc016a63e31c5749f16f60b3202414d071fc50573 + md5: 17c38aaf14c640b85c4617ccb59c1146 depends: - - libhwloc >=2.11.2,<2.11.3.0a0 + - libhwloc >=2.12.1,<2.12.2.0a0 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 - license_family: APACHE purls: [] - size: 151460 - timestamp: 1732982860332 -- conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.1.0-pyhd8ed1ab_0.conda - sha256: a83c83f5e622a2f34fb1d179c55c3ff912429cd0a54f9f3190ae44a0fdba2ad2 - md5: a15c62b8a306b8978f094f76da2f903f + size: 155714 + timestamp: 1762510341121 +- conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.1-pyhcf101f3_0.conda + sha256: 60c58dca39b30c3d1e2d8a474fe71c04537b8a5e42b9759706129f36100c84bf + md5: c07c341cc6ab9ed17b5a087e4bc954d0 depends: - - python >=3.9 + - python >=3.10 + - python license: BSD-2-Clause - license_family: BSD purls: - - pkg:pypi/tblib?source=compressed-mapping - size: 17914 - timestamp: 1743515657639 + - pkg:pypi/tblib?source=hash-mapping + size: 19264 + timestamp: 1762444129641 - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh0d859eb_0.conda sha256: b300557c0382478cf661ddb520263508e4b3b5871b471410450ef2846e8c352c md5: efba281bbdae5f6b0a1d53c6d4a97c93 @@ -9137,28 +9366,18 @@ packages: purls: [] size: 3466348 timestamp: 1748388121356 -- conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda - sha256: 34f3a83384ac3ac30aefd1309e69498d8a4aa0bf2d1f21c645f79b180e378938 - md5: b0dd904de08b7db706167240bf37b164 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/toml?source=hash-mapping - size: 22132 - timestamp: 1734091907682 -- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda - sha256: 18636339a79656962723077df9a56c0ac7b8a864329eb8f847ee3d38495b863e - md5: ac944244f1fed2eb49bae07193ae8215 +- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda + sha256: cb77c660b646c00a48ef942a9e1721ee46e90230c7c570cdeb5a893b5cce9bff + md5: d2732eb636c264dc9aa4cbee404b1a53 depends: - - python >=3.9 + - python >=3.10 + - python license: MIT license_family: MIT purls: - - pkg:pypi/tomli?source=hash-mapping - size: 19167 - timestamp: 1733256819729 + - pkg:pypi/tomli?source=compressed-mapping + size: 20973 + timestamp: 1760014679845 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.2.0-pyhd8ed1ab_0.conda sha256: 304834f2438017921d69f05b3f5a6394b42dc89a90a6128a46acbf8160d377f6 md5: 32e37e8fe9ef45c637ee38ad51377769 @@ -9178,37 +9397,37 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/tomlkit?source=compressed-mapping + - pkg:pypi/tomlkit?source=hash-mapping size: 38777 timestamp: 1749127286558 -- conda: https://conda.anaconda.org/conda-forge/noarch/toolz-1.0.0-pyhd8ed1ab_1.conda - sha256: eda38f423c33c2eaeca49ed946a8d3bf466cc3364970e083a65eb2fd85258d87 - md5: 40d0ed782a8aaa16ef248e68c06c168d +- conda: https://conda.anaconda.org/conda-forge/noarch/toolz-1.1.0-pyhd8ed1ab_1.conda + sha256: 4e379e1c18befb134247f56021fdf18e112fb35e64dd1691858b0a0f3bea9a45 + md5: c07a6153f8306e45794774cf9b13bd32 depends: - - python >=3.9 + - python >=3.10 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/toolz?source=hash-mapping - size: 52475 - timestamp: 1733736126261 -- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py313h536fd9c_0.conda - sha256: 282c9c3380217119c779fc4c432b0e4e1e42e9a6265bfe36b6f17f6b5d4e6614 - md5: e9434a5155db25c38ade26f71a2f5a48 + size: 53978 + timestamp: 1760707830681 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py313h07c4f96_2.conda + sha256: 8ef12814ebf787553b351c919d40a599e2331aefec639aef5ce6117cbcfc6a28 + md5: 7824f18e343d1f846dcde7b23c9bf31a depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/tornado?source=hash-mapping - size: 873269 - timestamp: 1748003477089 -- conda: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.1-py313h63b0ddb_0.conda - sha256: 16dc65432ce637d64475c4f02233be2d905edac9c1dba25419bfd5b8055d52b4 - md5: 7554d07cbe64f41c73a403e99bccf3c6 + size: 871569 + timestamp: 1762506888003 +- conda: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.2-py313hf050af9_2.conda + sha256: df2904c26237af8e3edcc84ce495465cdd82e23c0a7e100a401ce9caebef6e50 + md5: b3269a8a3f36be79609e87a9699153b4 depends: - __osx >=10.13 - python >=3.13,<3.14.0a0 @@ -9217,23 +9436,23 @@ packages: license_family: Apache purls: - pkg:pypi/tornado?source=hash-mapping - size: 874905 - timestamp: 1748003585372 -- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.1-py313ha7868ed_0.conda - sha256: 4d5511a98b3450157f40479eb3d00bbf3c4741c97149e2914258f71715c5cb47 - md5: a6a7c54e5dfc3bfad645e714cc14854c + size: 876654 + timestamp: 1762507291296 +- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.2-py313h5ea7bf4_2.conda + sha256: 79a13678078dbdcb800b75d32e7d60f460a2284f1d6ede15ff5478b656608a28 + md5: 81bf54645cb6686c47158450cd913ec2 depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/tornado?source=hash-mapping - size: 878044 - timestamp: 1748003914685 + size: 876064 + timestamp: 1762506921139 - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda sha256: 11e2c85468ae9902d24a27137b6b39b4a78099806e551d390e394a8c34b48e40 md5: 9efbfdc37242619130ea42b1cc4ed861 @@ -9256,29 +9475,29 @@ packages: - pkg:pypi/traitlets?source=hash-mapping size: 110051 timestamp: 1733367480074 -- conda: https://conda.anaconda.org/conda-forge/noarch/traittypes-0.2.1-pyh9f0ad1d_2.tar.bz2 - sha256: 7025cbf881fcb0c872209da619e89a5facc4d428f2f04f6690bef481a8d10710 - md5: 7d32ccb5334a6822c28af3e864550618 +- conda: https://conda.anaconda.org/conda-forge/noarch/traittypes-0.2.3-pyh332efcf_0.conda + sha256: 67a77ce374a792fc6d8e4d56c83c21b6cf3a7f43b6e98c1db2cbed2254144d05 + md5: d22a0bf07f57cfb1240185961d182a8d depends: - - python - - traitlets >=4.2.2 + - python >=3.9 + - traitlets >=4.2.2,<6.0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/traittypes?source=hash-mapping - size: 10119 - timestamp: 1600843475481 -- conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2025.5.9.12-pyhd8ed1ab_0.conda - sha256: 455b7b0dc0cf7e4a6fcc41455b4fd7f646b3b842e6dc0d894438366827d7d9b2 - md5: 764db08a8d868de9e377d88277c75d83 + size: 13283 + timestamp: 1761131966141 +- conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2025.9.11.17-pyhd8ed1ab_0.conda + sha256: 74807fa88e811aeaf3d2acd6221665efd9469caf8c57b4ee370b61f0528ff0ae + md5: fc3b129397a910cfe1350075a7ad7432 depends: - - python >=3.9 + - python >=3.10 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/trove-classifiers?source=hash-mapping - size: 19516 - timestamp: 1746817031708 + size: 19575 + timestamp: 1757677773672 - conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.4.4-pyhd8ed1ab_0.conda sha256: 591e03a61b4966a61b15a99f91d462840b6e77bf707ecb48690b24649fee921a md5: 8b2613dbfd4e2bc9080b2779b53fc210 @@ -9295,93 +9514,83 @@ packages: - pkg:pypi/typeguard?source=hash-mapping size: 35158 timestamp: 1750249264892 -- conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.16.0-pyh167b9f4_0.conda - sha256: 1ca70f0c0188598f9425a947afb74914a068bee4b7c4586eabb1c3b02fbf669f - md5: 985cc086b73bda52b2f8d66dcda460a1 +- conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhdb1f59b_0.conda + sha256: e4708f3f7f72e92511b1f6defca8cac520cef1af3cda92c3b7901731f7ddcb75 + md5: 27ec7c3f99366fa64228c3ee4ab49cbc depends: - - typer-slim-standard ==0.16.0 hf964461_0 - - python >=3.9 + - typer-slim-standard ==0.20.0 h65a100f_0 + - python >=3.10 - python license: MIT license_family: MIT purls: - - pkg:pypi/typer?source=compressed-mapping - size: 77232 - timestamp: 1748304246569 -- conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.16.0-pyhe01879c_0.conda - sha256: 54f859ddf5d3216fb602f54990c3ccefc65a30d1d98c400b998e520310630df3 - md5: 0d0a6c08daccb968c8c8fa93070658e2 + - pkg:pypi/typer?source=hash-mapping + size: 79367 + timestamp: 1760982314002 +- conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_0.conda + sha256: 08904a433b7ab6b2e0267576043a8397bb3ce7296d71aef34ae7d2506b2c192a + md5: d8ad446a00bbd434d6d03cdcc9b46524 depends: - - python >=3.9 + - python >=3.10 - click >=8.0.0 - typing_extensions >=3.7.4.3 - python constrains: - - typer 0.16.0.* + - typer 0.20.0.* - rich >=10.11.0 - shellingham >=1.3.0 license: MIT license_family: MIT purls: - - pkg:pypi/typer-slim?source=compressed-mapping - size: 46798 - timestamp: 1748304246569 -- conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.16.0-hf964461_0.conda - sha256: c35a0b232e9751ac871b733d4236eee887f64c3b1539ba86aecf175c3ac3dc02 - md5: c8fb6ddb4f5eb567d049f85b3f0c8019 + - pkg:pypi/typer-slim?source=hash-mapping + size: 47419 + timestamp: 1760982313997 +- conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h65a100f_0.conda + sha256: a4726dec9ec806757f5f0fee65f54f790d3f4854a869bd4cd2c2805c54b52d37 + md5: cfd4be2a44e441b12b58a7d04c9434e9 depends: - - typer-slim ==0.16.0 pyhe01879c_0 + - typer-slim ==0.20.0 pyhcf101f3_0 - rich - shellingham license: MIT license_family: MIT purls: [] - size: 5271 - timestamp: 1748304246569 -- conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20250516-pyhd8ed1ab_0.conda - sha256: 0fb78e97cad71ebf911958bf97777ec958a64a4621615a4dcc3ffb52cda7c6d0 - md5: e3465397ca4b5b60ba9fbc92ef0672f9 - depends: - - python >=3.9 - license: Apache-2.0 AND MIT - purls: - - pkg:pypi/types-python-dateutil?source=hash-mapping - size: 22634 - timestamp: 1747417327584 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.14.0-h32cad80_0.conda - sha256: b8cabfa54432b0f124c0af6b6facdf8110892914fa841ac2e80ab65ac52c1ba4 - md5: a1cdd40fc962e2f7944bc19e01c7e584 + size: 5294 + timestamp: 1760982314002 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c + md5: edd329d7d3a4ab45dcf905899a7a6115 depends: - - typing_extensions ==4.14.0 pyhe01879c_0 + - typing_extensions ==4.15.0 pyhcf101f3_0 license: PSF-2.0 license_family: PSF purls: [] - size: 90310 - timestamp: 1748959427551 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.1-pyhd8ed1ab_0.conda - sha256: 4259a7502aea516c762ca8f3b8291b0d4114e094bdb3baae3171ccc0900e722f - md5: e0c3cd765dc15751ee2f0b03cd015712 + size: 91383 + timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_0.conda + sha256: 8aaf69b828c2b94d0784f18f70f11aa032950d304e57e88467120b45c18c24fd + md5: 399701494e731ce73fdd86c185a3d1b4 depends: - - python >=3.9 + - python >=3.10 - typing_extensions >=4.12.0 license: MIT license_family: MIT purls: - pkg:pypi/typing-inspection?source=compressed-mapping - size: 18809 - timestamp: 1747870776989 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.14.0-pyhe01879c_0.conda - sha256: 8561db52f278c5716b436da6d4ee5521712a49e8f3c70fcae5350f5ebb4be41c - md5: 2adcd9bb86f656d3d43bf84af59a1faf + size: 18799 + timestamp: 1759301271883 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 + md5: 0caa1af407ecff61170c9437a808404d depends: - - python >=3.9 + - python >=3.10 - python license: PSF-2.0 license_family: PSF purls: - pkg:pypi/typing-extensions?source=hash-mapping - size: 50978 - timestamp: 1748959427551 + size: 51692 + timestamp: 1756220668932 - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda sha256: 3088d5d873411a56bf988eee774559335749aed6f6c28e07bf933256afb9eb6c md5: f6d7aa696c67756a650e91e15e88223c @@ -9411,15 +9620,16 @@ packages: - pkg:pypi/uc-micro-py?source=hash-mapping size: 11199 timestamp: 1733784280160 -- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - sha256: db8dead3dd30fb1a032737554ce91e2819b43496a0db09927edf01c32b577450 - md5: 6797b005cd0f439c4c5c9ac565783700 +- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 + md5: 71b24316859acd00bdb8b38f5e2ce328 constrains: + - vc14_runtime >=14.29.30037 - vs2015_runtime >=14.29.30037 license: LicenseRef-MicrosoftWindowsSDK10 purls: [] - size: 559710 - timestamp: 1728377334097 + size: 694692 + timestamp: 1756385147981 - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda sha256: e0eb6c8daf892b3056f08416a96d68b0a358b7c46b99c8a50481b22631a4dfc0 md5: e7cb0f5745e4c5035a460248334af7eb @@ -9458,35 +9668,35 @@ packages: - pkg:pypi/userpath?source=hash-mapping size: 14292 timestamp: 1735925027874 -- conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.7.14-h2f11bb8_0.conda - sha256: 79df92de78f2511e47a5c497ac4800cc18d77c259ac957444cb79b8318c30574 - md5: c0c496dd8d878f632beec92e3ab87104 +- conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.9.8-h76e24b7_0.conda + sha256: 3a0fdfb99e3c2e228991b078ff4495cb8462db589b8c00be32baa60d24306fb2 + md5: 23b31dda4cca5794d1cceb0f9faa3238 depends: - - libstdcxx >=13 - - libgcc >=13 + - libgcc >=14 + - libstdcxx >=14 + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 constrains: - __glibc >=2.17 license: Apache-2.0 OR MIT purls: [] - size: 14629678 - timestamp: 1750724569797 -- conda: https://conda.anaconda.org/conda-forge/osx-64/uv-0.7.14-h6914f18_0.conda - sha256: c511cb76dc17e1d259a157d494c432d4e94331ac14366271bca2d1a833680719 - md5: de88a4492eec02dca5ed93af2b066a07 + size: 17103477 + timestamp: 1762567870164 +- conda: https://conda.anaconda.org/conda-forge/osx-64/uv-0.9.8-h3315dae_0.conda + sha256: cc4c6245625ec973cabf76df7ace411da20565dc0d22fc18a46dde0ba3447d20 + md5: e470fc798df77c27b4d8df24336a3e58 depends: - - libcxx >=18 + - libcxx >=19 - __osx >=10.13 constrains: - __osx >=10.13 license: Apache-2.0 OR MIT purls: [] - size: 14298450 - timestamp: 1750724385271 -- conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.7.14-he94b42d_0.conda - sha256: 3ff429b53093ad6d3df72b3e626c69dd605f9a7051afb34d032a46f52a8423f6 - md5: 601200b06da7728c7abea234ec89c738 + size: 15989903 + timestamp: 1762567632356 +- conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.9.8-h3bd95fe_0.conda + sha256: 4c58c598763bb67846433faa840a8b67900fd94bee21b20ab1de190aa689821d + md5: f1daf65eb0cf5b52daccc7942920708e depends: - vc >=14.3,<15 - vc14_runtime >=14.44.35208 @@ -9496,150 +9706,164 @@ packages: - ucrt >=10.0.20348.0 license: Apache-2.0 OR MIT purls: [] - size: 15584322 - timestamp: 1750724413377 -- conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.34.3-pyh31011fe_0.conda - sha256: 4edebc7b6b96ebf92db8b5488c4b39594982eab79db44b267d8a3502e12b051b - md5: 1520c1396715d45d02f5aa045854a65c + size: 17336615 + timestamp: 1762567488942 +- conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.38.0-pyh31011fe_0.conda + sha256: 32e637726fd7cfeb74058e829b116e17514d001846fef56d8c763ec9ec5ac887 + md5: d3aa78bc38d9478e9eed5f128ba35f41 depends: - __unix - click >=7.0 - h11 >=0.8 - - python >=3.9 + - python >=3.10 - typing_extensions >=4.0 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/uvicorn?source=compressed-mapping - size: 49042 - timestamp: 1748779747595 -- conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.34.3-pyh5737063_0.conda - sha256: 58f178c8573c14a2e8a6967d110c7d70d69f5afb434d994c2ed3d0e0f9b58d40 - md5: cbb28206ddc7c92c3313fc9a77caf850 + - pkg:pypi/uvicorn?source=hash-mapping + size: 51717 + timestamp: 1760803935306 +- conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.38.0-pyh5737063_0.conda + sha256: ebb120ec1626ced65f3965c08f9ac58d57a18488f991a87dad89f002a2094cb2 + md5: 8fb44dcece55529465f9e6f3e40eef61 depends: - __win - click >=7.0 - h11 >=0.8 - - python >=3.9 + - python >=3.10 - typing_extensions >=4.0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/uvicorn?source=hash-mapping - size: 49242 - timestamp: 1748779958668 -- conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.34.3-h31011fe_0.conda - sha256: 7de45d9cc878424f65b6ae936f35314e8abc031b60c464258c0a7ef65778c548 - md5: 6d80b382cafd45723e75dccef6496c67 + size: 51772 + timestamp: 1760804061872 +- conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.38.0-h31011fe_0.conda + sha256: 3629a349257c0e129cbb84fd593759a31d68ac1219c0af8b8ed89b95b9574c9b + md5: 1ce870d7537376362672f5ff57109529 depends: - __unix - httptools >=0.6.3 - python-dotenv >=0.13 - pyyaml >=5.1 - - uvicorn 0.34.3 pyh31011fe_0 + - uvicorn 0.38.0 pyh31011fe_0 - uvloop >=0.14.0,!=0.15.0,!=0.15.1 - watchfiles >=0.13 - websockets >=10.4 license: BSD-3-Clause license_family: BSD purls: [] - size: 7613 - timestamp: 1748779748439 -- conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.34.3-h5737063_0.conda - sha256: 37cb42595f17d5642e191a527cba299574cbecf0a6aca0cd7406596095168f5f - md5: 96e2a82d4a173b7542bd7df82e7aca20 + size: 7719 + timestamp: 1760803936446 +- conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.38.0-h5737063_0.conda + sha256: ba4a9d4962a671efd2b911c0be9f576beecff8cc606344a46e0c67720e9f5dbc + md5: 816b80d606a73c2ffaf55e84c3ff2516 depends: - __win - colorama >=0.4 - httptools >=0.6.3 - python-dotenv >=0.13 - pyyaml >=5.1 - - uvicorn 0.34.3 pyh5737063_0 + - uvicorn 0.38.0 pyh5737063_0 - watchfiles >=0.13 - websockets >=10.4 license: BSD-3-Clause license_family: BSD purls: [] - size: 8127 - timestamp: 1748779962006 -- conda: https://conda.anaconda.org/conda-forge/linux-64/uvloop-0.21.0-py313h536fd9c_1.conda - sha256: fa889930e1f6482a20a4ee12a8670e31b1c8704a6282b9172112379809d763c3 - md5: da0d10783ecd3b329ab2a16cab096980 + size: 8179 + timestamp: 1760804064891 +- conda: https://conda.anaconda.org/conda-forge/linux-64/uvloop-0.22.1-py313h07c4f96_1.conda + sha256: 77a220ecf6c1467f94d6adda5fb1296f558f3f3044842dc0a52881eab5908dc0 + md5: 266caaa8701a13482ea924a77897b1e4 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libuv >=1.49.2,<2.0a0 + - libgcc >=14 + - libuv >=1.51.0,<2.0a0 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: MIT OR Apache-2.0 purls: - pkg:pypi/uvloop?source=hash-mapping - size: 703782 - timestamp: 1730214503009 -- conda: https://conda.anaconda.org/conda-forge/osx-64/uvloop-0.21.0-py313hb558fbc_1.conda - sha256: 936b0551c6107ad0a2dff2495dc17b7dc79f0b81b809d4696cf21ab373b0828e - md5: 7c2ad767230b7e79bf53e56c6a8a29e6 + size: 590601 + timestamp: 1762472969139 +- conda: https://conda.anaconda.org/conda-forge/osx-64/uvloop-0.22.1-py313hf050af9_1.conda + sha256: 962b436ee710fd353cf420ed538c35376d3b5d5cd58655755396001b0c38b5ef + md5: 7133d80ca7ffd5d6538a8fbaf8d32c20 depends: - __osx >=10.13 - - libuv >=1.49.2,<2.0a0 + - libuv >=1.51.0,<2.0a0 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: MIT OR Apache-2.0 purls: - pkg:pypi/uvloop?source=hash-mapping - size: 562010 - timestamp: 1730214643478 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_26.conda - sha256: b388d88e04aa0257df4c1d28f8d85d985ad07c1e5645aa62335673c98704c4c6 - md5: 18b6bf6f878501547786f7bf8052a34d + size: 506247 + timestamp: 1762473096616 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_32.conda + sha256: 82250af59af9ff3c6a635dd4c4764c631d854feb334d6747d356d949af44d7cf + md5: ef02bbe151253a72b8eda264a935db66 depends: - - vc14_runtime >=14.44.35208 + - vc14_runtime >=14.42.34433 track_features: - vc14 license: BSD-3-Clause license_family: BSD purls: [] - size: 17914 - timestamp: 1750371462857 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_26.conda - sha256: 7bad6e25a7c836d99011aee59dcf600b7f849a6fa5caa05a406255527e80a703 - md5: 14d65350d3f5c8ff163dc4f76d6e2830 + size: 18861 + timestamp: 1760418772353 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda + sha256: e3a3656b70d1202e0d042811ceb743bd0d9f7e00e2acdf824d231b044ef6c0fd + md5: 378d5dcec45eaea8d303da6f00447ac0 + depends: + - ucrt >=10.0.20348.0 + - vcomp14 14.44.35208 h818238b_32 + constrains: + - vs2015_runtime 14.44.35208.* *_32 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + size: 682706 + timestamp: 1760418629729 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda + sha256: f3790c88fbbdc55874f41de81a4237b1b91eab75e05d0e58661518ff04d2a8a1 + md5: 58f67b437acbf2764317ba273d731f1d depends: - ucrt >=10.0.20348.0 constrains: - - vs2015_runtime 14.44.35208.* *_26 + - vs2015_runtime 14.44.35208.* *_32 license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime license_family: Proprietary purls: [] - size: 756109 - timestamp: 1750371459116 -- conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.31.2-pyhd8ed1ab_0.conda - sha256: 763dc774200b2eebdf5437b112834c5455a1dd1c9b605340696950277ff36729 - md5: c0600c1b374efa7a1ff444befee108ca + size: 114846 + timestamp: 1760418593847 +- conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.35.4-pyhd8ed1ab_0.conda + sha256: 77193c99c6626c58446168d3700f9643d8c0dab1f6deb6b9dd039e6872781bfb + md5: cfccfd4e8d9de82ed75c8e2c91cab375 depends: - distlib >=0.3.7,<1 - filelock >=3.12.2,<4 - platformdirs >=3.9.1,<5 - - python >=3.9 + - python >=3.10 + - typing_extensions >=4.13.2 license: MIT license_family: MIT purls: - pkg:pypi/virtualenv?source=hash-mapping - size: 4133755 - timestamp: 1746781585998 -- conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.44.35208-h38c0c73_26.conda - sha256: d18d77c8edfbad37fa0e0bb0f543ad80feb85e8fe5ced0f686b8be463742ec0b - md5: 312f3a0a6b3c5908e79ce24002411e32 + size: 4401341 + timestamp: 1761726489722 +- conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.44.35208-h38c0c73_32.conda + sha256: 65cea43f4de99bc81d589e746c538908b2e95aead9042fecfbc56a4d14684a87 + md5: dfc1e5bbf1ecb0024a78e4e8bd45239d depends: - vc14_runtime >=14.44.35208 license: BSD-3-Clause license_family: BSD purls: [] - size: 17888 - timestamp: 1750371463202 -- conda: https://conda.anaconda.org/conda-forge/linux-64/watchdog-6.0.0-py313h78bf25f_0.conda - sha256: 2099b8d4409e727558c9ddb935b48567f0d9b4e31f8e865f35bcd3f5bef5bdc3 - md5: 8534476263f09c0ade70411ce59f75f6 + size: 18919 + timestamp: 1760418632059 +- conda: https://conda.anaconda.org/conda-forge/linux-64/watchdog-6.0.0-py313h78bf25f_1.conda + sha256: 73225611a442fdebc9d333951037a428f6e9b8449d4194030457c026970a3283 + md5: d643d87d7df61d3d47db87bdd4571ec6 depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 @@ -9648,11 +9872,11 @@ packages: license_family: APACHE purls: - pkg:pypi/watchdog?source=hash-mapping - size: 142789 - timestamp: 1730492986088 -- conda: https://conda.anaconda.org/conda-forge/osx-64/watchdog-6.0.0-py313h63b0ddb_0.conda - sha256: ab2bf709f3cfd270a5d8491188e05fa68d92b9f84a30269e4db391093cbb9049 - md5: d83c209755e41be09f8107fbc884fa91 + size: 144014 + timestamp: 1756135338277 +- conda: https://conda.anaconda.org/conda-forge/osx-64/watchdog-6.0.0-py313h585f44e_1.conda + sha256: 63961c1cac16f0f2dbb32f2499b16d59895a4727df7afae2c61e1c91f083e048 + md5: f9f9ec9a5a54a9b2a8cf8891fe934be5 depends: - __osx >=10.13 - python >=3.13,<3.14.0a0 @@ -9662,11 +9886,11 @@ packages: license_family: APACHE purls: - pkg:pypi/watchdog?source=hash-mapping - size: 151270 - timestamp: 1730493213458 -- conda: https://conda.anaconda.org/conda-forge/win-64/watchdog-6.0.0-py313hfa70ccb_0.conda - sha256: 213d520704e528b2273b2701f0961048c5bdbefbe4db5cdabcf9d01d4322fbf8 - md5: 9593f7b5c1aa4be66a9945c4f1e9f043 + size: 151558 + timestamp: 1756135500585 +- conda: https://conda.anaconda.org/conda-forge/win-64/watchdog-6.0.0-py313hfa70ccb_1.conda + sha256: 06263427dcd0100706d26c0461f2ff8356f23f4b2ee047f67d0cd7f073e2c842 + md5: ff8bfc0c2479faccdfa9ec9859ed663b depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 @@ -9675,15 +9899,15 @@ packages: license_family: APACHE purls: - pkg:pypi/watchdog?source=hash-mapping - size: 167930 - timestamp: 1730493160417 -- conda: https://conda.anaconda.org/conda-forge/linux-64/watchfiles-1.1.0-py313h920b4c0_0.conda - sha256: 5a27ec51a5de9a251ce7078739d0fc9301510992405fae5a29784c5daac3caeb - md5: c9f7604d02c82ec812444d5ccee625bd + size: 168440 + timestamp: 1756135584322 +- conda: https://conda.anaconda.org/conda-forge/linux-64/watchfiles-1.1.1-py313h5c7d99a_0.conda + sha256: 11a07764137af9bcf29e9e26671c1be1ea1302f7dd7075a4d41481489883eaff + md5: 9373034735566df29779429f0c0de511 depends: - __glibc >=2.17,<3.0.a0 - anyio >=3.0.0 - - libgcc >=13 + - libgcc >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 constrains: @@ -9692,11 +9916,11 @@ packages: license_family: MIT purls: - pkg:pypi/watchfiles?source=hash-mapping - size: 420988 - timestamp: 1750054029977 -- conda: https://conda.anaconda.org/conda-forge/osx-64/watchfiles-1.1.0-py313h3c055b9_0.conda - sha256: 118319c4b1f4bc9a2104c61e9b15b439e694ea82b619cafa89355452c18f6fd7 - md5: 031f7426f9be8759d646c3cec4f30352 + size: 420641 + timestamp: 1760456759391 +- conda: https://conda.anaconda.org/conda-forge/osx-64/watchfiles-1.1.1-py313ha265c4a_0.conda + sha256: 7763e5704bbb0c0a69e47542bed8cda8f328710b6427da20bcdcb4bf3affe1d4 + md5: 08bf0d738516aedd4d22d163e7f80926 depends: - __osx >=10.13 - anyio >=3.0.0 @@ -9708,46 +9932,46 @@ packages: license_family: MIT purls: - pkg:pypi/watchfiles?source=hash-mapping - size: 377217 - timestamp: 1750054226372 -- conda: https://conda.anaconda.org/conda-forge/win-64/watchfiles-1.1.0-py313hf3b5b86_0.conda - sha256: dbe6ad52cae1b30c4147a4c97e7f0bdb7cf5bfc08bb8e8cf2301b4aa6956ee12 - md5: c525096add47054427ea3a7ce8b30ffe + size: 377651 + timestamp: 1760457095573 +- conda: https://conda.anaconda.org/conda-forge/win-64/watchfiles-1.1.1-py313hf61f64f_0.conda + sha256: 303e530230db6073a798582551e79a5afe3ed95acd294b19048fcba75d0c0e5c + md5: 278ccf48b6154f12a680f0521043f869 depends: - anyio >=3.0.0 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: - pkg:pypi/watchfiles?source=hash-mapping - size: 308441 - timestamp: 1750054555332 -- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda - sha256: f21e63e8f7346f9074fd00ca3b079bd3d2fa4d71f1f89d5b6934bf31446dc2a5 - md5: b68980f2495d096e71c7fd9d7ccf63e6 + size: 303712 + timestamp: 1760457522687 +- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.14-pyhd8ed1ab_0.conda + sha256: e311b64e46c6739e2a35ab8582c20fa30eb608da130625ed379f4467219d4813 + md5: 7e1e5ff31239f9cd5855714df8a3783d depends: - - python >=3.9 + - python >=3.10 license: MIT license_family: MIT purls: - pkg:pypi/wcwidth?source=hash-mapping - size: 32581 - timestamp: 1733231433877 -- conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.11.1-pyhd8ed1ab_0.conda - sha256: 08315dc2e61766a39219b2d82685fc25a56b2817acf84d5b390176080eaacf99 - md5: b49f7b291e15494aafb0a7d74806f337 + size: 33670 + timestamp: 1758622418893 +- conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + sha256: 21f6c8a20fe050d09bfda3fb0a9c3493936ce7d6e1b3b5f8b01319ee46d6c6f6 + md5: 6639b6b0d8b5a284f027a2003669aa65 depends: - - python >=3.9 + - python >=3.10 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/webcolors?source=hash-mapping - size: 18431 - timestamp: 1733359823938 + size: 18987 + timestamp: 1761899393153 - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda sha256: 19ff205e138bb056a46f9e3839935a2e60bd1cf01c8241a5e172a422fed4f9c6 md5: 2841eb5bfc75ce15e9a0054b98dcd64d @@ -9759,70 +9983,73 @@ packages: - pkg:pypi/webencodings?source=hash-mapping size: 15496 timestamp: 1733236131358 -- conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.8.0-pyhd8ed1ab_1.conda - sha256: 1dd84764424ffc82030c19ad70607e6f9e3b9cb8e633970766d697185652053e - md5: 84f8f77f0a9c6ef401ee96611745da8f +- conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + sha256: 42a2b61e393e61cdf75ced1f5f324a64af25f347d16c60b14117393a98656397 + md5: 2f1ed718fcd829c184a6d4f0f2e07409 depends: - - python >=3.9 + - python >=3.10 license: Apache-2.0 license_family: APACHE purls: - pkg:pypi/websocket-client?source=hash-mapping - size: 46718 - timestamp: 1733157432924 -- conda: https://conda.anaconda.org/conda-forge/linux-64/websockets-15.0.1-py313h536fd9c_0.conda - sha256: 16c0e5acfa57f9fcd675b4210844305ff9552fac23bc6b30a937d0e920d3b6b3 - md5: 386e5d30ed6c4e5fb99d5a163a3f7028 + size: 61391 + timestamp: 1759928175142 +- conda: https://conda.anaconda.org/conda-forge/linux-64/websockets-15.0.1-py313h54dd161_2.conda + sha256: 9de398238e7737d79a36db16f49b1e82b032c7ea7458f8af7396653c5f9bf6bc + md5: d6dccef73e6b207a6ad0095e19c7690f depends: + - python + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/websockets?source=hash-mapping - size: 273601 - timestamp: 1741285585784 -- conda: https://conda.anaconda.org/conda-forge/osx-64/websockets-15.0.1-py313h63b0ddb_0.conda - sha256: 9b6cdd755edf96a00595d7f8395334751a6cd0a9416f5247465900ff6b83e753 - md5: 30d305da4d2ccbea407c7db155a5c54b + size: 364253 + timestamp: 1756476348604 +- conda: https://conda.anaconda.org/conda-forge/osx-64/websockets-15.0.1-py313h6865ccc_2.conda + sha256: f1dfd801e487aa46ba2750422c22abbb80d95efdf798b587655295f85f572776 + md5: cdc04e0138416cb02bb184d8e96b426a depends: + - python - __osx >=10.13 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/websockets?source=hash-mapping - size: 273185 - timestamp: 1741285638203 -- conda: https://conda.anaconda.org/conda-forge/win-64/websockets-15.0.1-py313ha7868ed_0.conda - sha256: c2f1f6fdb55077e5eb8ffab9b274305a9e09745329fde3d943806e9bb330698e - md5: 9f7310955fd23d394f9677549c4bf5d2 + size: 364776 + timestamp: 1756476419539 +- conda: https://conda.anaconda.org/conda-forge/win-64/websockets-15.0.1-py313h5fd188c_2.conda + sha256: 75cd0f0137fde98fef5c30b30fb75825c248e06b0ae1704e903e6a226a8893fb + md5: d613174559c775a83ba68349d40de23f depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/websockets?source=hash-mapping - size: 323574 - timestamp: 1741286027886 -- conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.14-pyhd8ed1ab_0.conda - sha256: 7df3620c88343f2d960a58a81b79d4e4aa86ab870249e7165db7c3e2971a2664 - md5: 2f1f99b13b9d2a03570705030a0b3e7c + size: 421317 + timestamp: 1756476374762 +- conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.15-pyhd8ed1ab_0.conda + sha256: 826af5e2c09e5e45361fa19168f46ff524e7a766022615678c3a670c45895d9a + md5: dc257b7e7cad9b79c1dfba194e92297b depends: - - python >=3.9 + - python >=3.10 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/widgetsnbextension?source=hash-mapping - size: 889285 - timestamp: 1744291155057 + size: 889195 + timestamp: 1762040404362 - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda sha256: 93807369ab91f230cf9e6e2a237eaa812492fe00face5b38068735858fba954f md5: 46e441ba871f524e2b067929da3051c2 @@ -9841,23 +10068,23 @@ packages: license_family: MIT purls: [] size: 1176306 -- conda: https://conda.anaconda.org/conda-forge/linux-64/wrapt-1.17.2-py313h536fd9c_0.conda - sha256: d0dafa5e2618e3fb6fccf5bfc3d3f65f29edc46582a7ebfcc231b61c1e6d61a9 - md5: e6795cc8e926da2e2abb634a46c4d60c +- conda: https://conda.anaconda.org/conda-forge/linux-64/wrapt-1.17.3-py313h07c4f96_1.conda + sha256: 3688598866224e3fbeed8a74f12fd0a3c19dadcb931ce778bdc6cc2e04621b3b + md5: c2662497e9a9ff2153753682f53989c9 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-2-Clause license_family: BSD purls: - pkg:pypi/wrapt?source=hash-mapping - size: 64497 - timestamp: 1736869638431 -- conda: https://conda.anaconda.org/conda-forge/osx-64/wrapt-1.17.2-py313h63b0ddb_0.conda - sha256: 796b1bd250909798d513fb7bb38f62a04cfb0ac7bef59a9d671acf9f2e7fbc19 - md5: 8269b251c18248e87c2d3ebb26d81893 + size: 64865 + timestamp: 1756851811052 +- conda: https://conda.anaconda.org/conda-forge/osx-64/wrapt-1.17.3-py313h585f44e_1.conda + sha256: dd8f1b31d78220dae5fd046d53d4c4b90251661086b44aef074e7775398719fc + md5: 765dc9b39fc2d62e1351c3a26e316607 depends: - __osx >=10.13 - python >=3.13,<3.14.0a0 @@ -9866,23 +10093,23 @@ packages: license_family: BSD purls: - pkg:pypi/wrapt?source=hash-mapping - size: 60989 - timestamp: 1736869846646 -- conda: https://conda.anaconda.org/conda-forge/win-64/wrapt-1.17.2-py313ha7868ed_0.conda - sha256: f0182c77fc77c8123e033239dec4dda7eb7a834c72c3fa554c47c5c96785ffca - md5: 45a0cba5661880a1af9bf7e84909e59d + size: 61239 + timestamp: 1756851742749 +- conda: https://conda.anaconda.org/conda-forge/win-64/wrapt-1.17.3-py313h5ea7bf4_1.conda + sha256: 260a3295f39565c28be9232a11ca7ee435af6e9366ffd2569ff29a63e7c144a0 + md5: 3e199c8db04833fe628867462aeaca24 depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: BSD-2-Clause license_family: BSD purls: - pkg:pypi/wrapt?source=hash-mapping - size: 62824 - timestamp: 1736870265811 + size: 63385 + timestamp: 1756851987645 - pypi: ../eozilla/wraptile name: wraptile version: 0.0.8 @@ -9897,41 +10124,41 @@ packages: - procodile>=0.0.7 requires_python: '>=3.10' editable: true -- conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.6.1-pyhd8ed1ab_1.conda - sha256: e27b45ca791cfbcad37d64b8615d0672d94aafa00b014826fcbca2ce18bd1cc0 - md5: 145c6f2ac90174d9ad1a2a51b9d7c1dd +- conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.10.1-pyhcf101f3_1.conda + sha256: 57bfac2a070d2c63d34c1d75a409cb92e788ac42e658e9d9349cd19b12888ce7 + md5: 515d0ed77a942ad39fa94cf636dcde44 depends: - - numpy >=1.24 - - packaging >=23.2 - - pandas >=2.1 - - python >=3.10 + - python >=3.11 + - numpy >=1.26 + - packaging >=24.1 + - pandas >=2.2 + - python constrains: - - scipy >=1.11 - - dask-core >=2023.11 - - bottleneck >=1.3 - - zarr >=2.16 - - flox >=0.7 - - h5py >=3.8 - - iris >=3.7 - - cartopy >=0.22 - - numba >=0.57 - - sparse >=0.14 - - pint >=0.22 - - distributed >=2023.11 - - hdf5 >=1.12 - - seaborn-base >=0.13 - - nc-time-axis >=1.4 - - matplotlib-base >=3.8 - - toolz >=0.12 - - netcdf4 >=1.6.0 + - bottleneck >=1.4 + - cartopy >=0.23 - cftime >=1.6 + - dask-core >=2024.6 + - distributed >=2024.6 + - flox >=0.9 - h5netcdf >=1.3 + - h5py >=3.11 + - hdf5 >=1.14 + - iris >=3.9 + - matplotlib-base >=3.8 + - nc-time-axis >=1.4 + - netcdf4 >=1.6.0 + - numba >=0.60 + - pint >=0.24 + - scipy >=1.13 + - seaborn-base >=0.13 + - sparse >=0.15 + - toolz >=0.12 + - zarr >=2.18 license: Apache-2.0 - license_family: APACHE purls: - - pkg:pypi/xarray?source=hash-mapping - size: 879913 - timestamp: 1749743321359 + - pkg:pypi/xarray?source=compressed-mapping + size: 981473 + timestamp: 1762776862272 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda sha256: ed10c9283974d311855ae08a16dfd7e56241fac632aec3b92e3cfe73cff31038 md5: f6ebe2cb3f82ba6c057dde5d9debe4f7 @@ -9998,106 +10225,119 @@ packages: purls: [] size: 69920 timestamp: 1727795651979 -- conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.4.0-pyhd8ed1ab_0.conda - sha256: ac6d4d4133b1e0f69075158cdf00fccad20e29fc6cc45faa480cec37a84af6ae - md5: 5663fa346821cd06dc1ece2c2600be2c +- conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.10.0-pyhd8ed1ab_0.conda + sha256: c1b83ca08b11b5e8fa610e5e9721cf62bc67300fb951b7a189a0882565e2b391 + md5: c98904dfa356df2e386db8af043be202 depends: - python >=3.8 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/xyzservices?source=hash-mapping - size: 49477 - timestamp: 1745598150265 -- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 - sha256: a4e34c710eeb26945bdbdaba82d3d74f60a78f54a874ec10d373811a5d217535 - md5: 4cb3ad778ec2d5a7acbdf254eb1c42ae + size: 50234 + timestamp: 1761842339966 +- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad + md5: a77f85f77be52ff59391544bfe73390a depends: - - libgcc-ng >=9.4.0 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 license: MIT license_family: MIT purls: [] - size: 89141 - timestamp: 1641346969816 -- conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2 - sha256: 5301417e2c8dea45b401ffee8df3957d2447d4ce80c83c5ff151fc6bfe1c4148 - md5: d7e08fcf8259d742156188e8762b4d20 + size: 85189 + timestamp: 1753484064210 +- conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda + sha256: a335161bfa57b64e6794c3c354e7d49449b28b8d8a7c4ed02bf04c3f009953f9 + md5: a645bb90997d3fc2aea0adf6517059bd + depends: + - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 84237 - timestamp: 1641347062780 -- conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h8ffe710_2.tar.bz2 - sha256: 4e2246383003acbad9682c7c63178e2e715ad0eb84f03a8df1fbfba455dfedc5 - md5: adbfb9f45d1004a26763652246a33764 + size: 79419 + timestamp: 1753484072608 +- conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda + sha256: 80ee68c1e7683a35295232ea79bcc87279d31ffeda04a1665efdb43cbd50a309 + md5: 433699cba6602098ae8957a323da2664 depends: - - vc >=14.1,<15.0a0 - - vs2015_runtime >=14.16.27012 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 license: MIT license_family: MIT purls: [] - size: 63274 - timestamp: 1641347623319 -- conda: https://conda.anaconda.org/conda-forge/noarch/zarr-3.0.8-pyhd8ed1ab_0.conda - sha256: 854caa950d31deca0c82ca2cdf45c19a47484b9838c7e357d967d42826c2766e - md5: fe4ccd05ad433a71414ac17137288809 + size: 63944 + timestamp: 1753484092156 +- conda: https://conda.anaconda.org/conda-forge/noarch/zarr-3.1.3-pyhcf101f3_0.conda + sha256: 3d494f058f1e8aef41c5fac202c45de26fdc7b169ed886522497a8b83615e8db + md5: 540ed093cbc10711485a385a58f34b00 depends: - - crc32c - - donfig >=0.8 - - numcodecs >=0.14 - - numpy >=1.25 - - packaging >=22.0 - python >=3.11 + - packaging >=22.0 + - numpy >=1.26 + - numcodecs >=0.14 - typing_extensions >=4.9 + - donfig >=0.8 + - crc32c + - python constrains: - fsspec >=2023.10.0 + - obstore >=0.5.1 license: MIT license_family: MIT purls: - pkg:pypi/zarr?source=hash-mapping - size: 214470 - timestamp: 1747730730866 -- conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h3b0a872_7.conda - sha256: a4dc72c96848f764bb5a5176aa93dd1e9b9e52804137b99daeebba277b31ea10 - md5: 3947a35e916fcc6b9825449affbf4214 + size: 290974 + timestamp: 1758255670714 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda + sha256: 47cfe31255b91b4a6fa0e9dbaf26baa60ac97e033402dbc8b90ba5fee5ffe184 + md5: 8035e5b54c08429354d5d64027041cad depends: + - libstdcxx >=14 + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - krb5 >=1.21.3,<1.22.0a0 - - libgcc >=13 + - libgcc >=14 - libsodium >=1.0.20,<1.0.21.0a0 - - libstdcxx >=13 + - krb5 >=1.21.3,<1.22.0a0 license: MPL-2.0 license_family: MOZILLA purls: [] - size: 335400 - timestamp: 1731585026517 -- conda: https://conda.anaconda.org/conda-forge/osx-64/zeromq-4.3.5-h7130eaa_7.conda - sha256: b932dce8c9de9a8ffbf0db0365d29677636e599f7763ca51e554c43a0c5f8389 - md5: 6a0a76cd2b3d575e1b7aaeb283b9c3ed + size: 310648 + timestamp: 1757370847287 +- conda: https://conda.anaconda.org/conda-forge/osx-64/zeromq-4.3.5-h6c33b1e_9.conda + sha256: 30aa5a2e9c7b8dbf6659a2ccd8b74a9994cdf6f87591fcc592970daa6e7d3f3c + md5: d940d809c42fbf85b05814c3290660f5 depends: - __osx >=10.13 - - krb5 >=1.21.3,<1.22.0a0 - - libcxx >=18 + - libcxx >=19 - libsodium >=1.0.20,<1.0.21.0a0 + - krb5 >=1.21.3,<1.22.0a0 license: MPL-2.0 license_family: MOZILLA purls: [] - size: 292112 - timestamp: 1731585246902 -- conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-ha9f60a1_7.conda - sha256: 15cc8e2162d0a33ffeb3f7b7c7883fd830c54a4b1be6a4b8c7ee1f4fef0088fb - md5: e03f2c245a5ee6055752465519363b1c + size: 259628 + timestamp: 1757371000392 +- conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h5bddc39_9.conda + sha256: 690cf749692c8ea556646d1a47b5824ad41b2f6dfd949e4cdb6c44a352fcb1aa + md5: a6c8f8ee856f7c3c1576e14b86cd8038 depends: - - krb5 >=1.21.3,<1.22.0a0 - - libsodium >=1.0.20,<1.0.21.0a0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libsodium >=1.0.20,<1.0.21.0a0 + - krb5 >=1.21.3,<1.22.0a0 license: MPL-2.0 license_family: MOZILLA purls: [] - size: 2527503 - timestamp: 1731585151036 + size: 265212 + timestamp: 1757370864284 - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_1.conda sha256: 5488542dceeb9f2874e726646548ecc5608060934d6f9ceaa7c6a48c61f9cc8d md5: e52c2ef711ccf31bb7f70ca87d144b9e @@ -10143,51 +10383,92 @@ packages: purls: [] size: 88544 timestamp: 1727963189976 -- conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py313h536fd9c_2.conda - sha256: ea9c542ef78c9e3add38bf1032e8ca5d18703114db353f6fca5c498f923f8ab8 - md5: a026ac7917310da90a98eac2c782723c +- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.2.5-hde8ca8f_0.conda + sha256: 3a8e7798deafd0722b6b5da50c36b7f361a80b30165d600f7760d569a162ff95 + md5: 1920c3502e7f6688d650ab81cd3775fd depends: - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: Zlib + license_family: Other + purls: [] + size: 110843 + timestamp: 1754587144298 +- conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.2.5-h55e386d_0.conda + sha256: c2942b36c59dbc152254c6e2e15ff21f8900e06e350b1bda4ebf656a2002d5f5 + md5: 692a62051af2270eb9c24e8f09e88db6 + depends: + - __osx >=10.13 + - libcxx >=19 + license: Zlib + license_family: Other + purls: [] + size: 109093 + timestamp: 1761842915854 +- conda: https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.2.5-h32d8bfd_0.conda + sha256: 67a3113acf3506f1cf1c72e0748742217a20edc6c1c1c19631f901c5e028d2bc + md5: dec092b1a069abafc38655ded65a7b29 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Zlib + license_family: Other + purls: [] + size: 111682 + timestamp: 1761842670565 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py313h54dd161_1.conda + sha256: e6921de3669e1bbd5d050a3b771b46a887e7f4ffeb1ddd5e4d9fb01062a2f6e9 + md5: 710d4663806d0f72b2fb414e936223b5 + depends: + - python - cffi >=1.11 - - libgcc >=13 - - python >=3.13,<3.14.0a0 + - zstd >=1.5.7,<1.5.8.0a0 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 - python_abi 3.13.* *_cp313 + - zstd >=1.5.7,<1.6.0a0 license: BSD-3-Clause - license_family: BSD purls: - pkg:pypi/zstandard?source=hash-mapping - size: 736909 - timestamp: 1745869790689 -- conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.23.0-py313h63b0ddb_2.conda - sha256: ab53cc54d0af1a8d85a50510209595d09c584101668f35c0fd3c4fbd59c4ece2 - md5: 3babd14037340de278106b258fdb28d9 + size: 471496 + timestamp: 1762512679097 +- conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.25.0-py313hcb05632_1.conda + sha256: eed36460cfd4afdcb5e3dbca1f493dd9251e90ad793680064efdeb72d95f16a0 + md5: da657125cfc67fe18e4499cf88dbe512 depends: - - __osx >=10.13 + - python - cffi >=1.11 - - python >=3.13,<3.14.0a0 + - zstd >=1.5.7,<1.5.8.0a0 + - __osx >=10.13 - python_abi 3.13.* *_cp313 + - zstd >=1.5.7,<1.6.0a0 license: BSD-3-Clause - license_family: BSD purls: - pkg:pypi/zstandard?source=hash-mapping - size: 696588 - timestamp: 1745869877231 -- conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.23.0-py313ha7868ed_2.conda - sha256: b7bfe264fe3810b1abfe7f80c0f21f470d7cc730ada7ce3b3d08a90cb871999c - md5: b4d967b4d695a2ba8554738b3649d754 + size: 468984 + timestamp: 1762512716065 +- conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.25.0-py313h5fd188c_1.conda + sha256: 5f751687a64cf5a6d69ad79aa437f45d6cc388d9e887dcdecff9d3b08cf7fd87 + md5: 46f6f9bb324a58a9b081bbc56ade37f2 depends: + - python - cffi >=1.11 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - zstd >=1.5.7,<1.5.8.0a0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + - zstd >=1.5.7,<1.6.0a0 license: BSD-3-Clause - license_family: BSD purls: - pkg:pypi/zstandard?source=hash-mapping - size: 449871 - timestamp: 1745870298072 + size: 380854 + timestamp: 1762512720226 - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda sha256: a4166e3d8ff4e35932510aaff7aa90772f84b4d07e9f6f83c614cba7ceefe0eb md5: 6432cb5d4ac0046c3ac0a8a0f95842f9 From ad43e87f2b9813fc97936d0ee80742a39b5b12d7 Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Thu, 13 Nov 2025 13:59:26 +0100 Subject: [PATCH 13/16] Docs and deps update --- README.md | 33 +- docs/index.md | 19 +- docs/installation.md | 162 ++++++++++ mkdocs.yml | 1 + pixi.lock | 738 +++++++++++++++++++++---------------------- pyproject.toml | 21 +- 6 files changed, 575 insertions(+), 399 deletions(-) create mode 100644 docs/installation.md diff --git a/README.md b/README.md index 64f021d..32910d2 100644 --- a/README.md +++ b/README.md @@ -120,19 +120,19 @@ Install the S2GOS controller packages as described in To run all checks, execute -```commandline +```bash pixi run checks ``` To run all tests, execute -```commandline +```bash pixi run tests ``` To generate a coverage report, execute -```commandline +```bash pixi run coverage ``` @@ -153,7 +153,7 @@ would likely be best to implement the required changes in the respective Eozilla packages. For this, check out the Eozilla sources directly next to this project's sources to achieve this folder structure: -```commandline +``` / ├── s2gos-controller/ │ ├── s2gos-client/ @@ -168,17 +168,24 @@ to this project's sources to achieve this folder structure: └── ... ``` -Then, during development, change `sen4cap-controller/pyproject.toml` -as follows +For development, change the root `pyproject.toml` file as follows -1. Comment out the dependencies `cuiman`, `gavicore`, and `wraptile` in the - `[project.dependencies]` table. +1. Comment out the dependencies `cuiman`, `gavicore`, etc. in the + `[tool.pixi.dependencies]` table. -2. Uncomment the editable PyPI dependencies for `cuiman`, `gavicore`, - and `wraptile` in the `[tool.pixi.pypi-dependencies]` table. +2. Uncomment the editable PyPI dependencies for `cuiman`, `gavicore`, etc. in + the `[tool.pixi.pypi-dependencies]` table. -Then run once more +The run -```commandline -pixi install +```bash +pixi i ``` + +to make the changes effective. Check with + +```bash +pixi ls +``` + +which should now list the Eozilla packages as editable. diff --git a/docs/index.md b/docs/index.md index 7572c44..0d2d751 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,13 +1,20 @@ # DTE-S2GOS Controller +The Python control layer for the ESA DTE-S2GOS synthetic scene generator service + ![logo.svg](assets/logo.svg){ .centered-logo width="300"} -
    -
    -The Python control layer for the ESA DTE-S2GOS synthetic scene generator service. +The _Digital Twin Earth Synthetic Scene Generator and Observation Simulator_ +(DTE-S2GOS) project consists in the development of a new component of the +[ESA Destination Earth Initiative](https://destination-earth.eu/) +to be implemented in the [ESA DestinE Platform](https://platform.destine.eu/) +as a pre-operational service. The primary objective of DTE-S2GOS is to develop a +comprehensive and accurate simulation framework that can generate physically +realistic synthetic 3D scenes of the Earth and simulate ground-based or spaceborne +remote sensing observations, among other with the +[Eradiate Radiative Transfer Model](https://github.com/eradiate/eradiate). + **Note, this project and its documentation is still in an early development stage.** -
    -
    [The Project](https://dte-s2gos.rayference.eu/about/){ .md-button .md-button--primary } -[Get Started](client-cli){ .md-button .md-button--primary } +[Get Started](installation){ .md-button .md-button--primary } diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..fc9fe2b --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,162 @@ +# Installation + +## Using pip + +The S2GOS controller packages are not yet deployed on PyPI, therefore +installing it as a package using `pip` is not yet available. + +## Using conda/mamba + +The S2GOS controller packages are not yet deployed on conda-forge, therefore +installing it using as a conda package using `conda` or `mamba` is not yet available. + +## Using pixi + +The S2GOS controller packages are not yet deployed on conda-forge, therefore +installing it as a conda package using `pixi` is not yet available. + +## Using GitHub + +To install the S2GOS controller packages from their sources on GitHub you'll +need to install both [git](https://git-scm.com/install/) and +[pixi](https://pixi.sh/latest/installation/) first. Then: + +```bash +git clone https://github.com/eo-tools/sen4cap-client.git +cd s2gos-controller +pixi install +pixi shell +``` + +The installed development environment includes also JupyterLab so the recommended +way to get started is to take a look at the notebooks in the `notebooks` folder. + +```bash +cd notebooks +jupyter-lab +``` + +## Getting started + +After installing the S2GOS controller packages in your Python environment +and activating it (conda/mamba: `conda activate `, pixi: `pixi shell`) +make sure the respective command-line tools are accessible: Type + +```bash +s2gos-server --help +``` + +and + +```bash +s2gos-client --help +``` + +to get an overview of the available commands and options. + +You can then run the S2GOS server with one of the development services +or use the deployed server. To run the development service with a local +process executor run + +```bash +s2gos-server dev -- wraptile.services.local:service +``` + +To run the S2GOS gateway server with a local Airflow instance (assuming +the local Airflow webserver runs on http://localhost:8080): + +```bash +s2gos-server dev -- wraptile.services.airflow:service --airflow-password=abcd1234 +``` + +The next step is configure the client, which will also serve as default configuration +for the client's Python API and its GUI: + +```bash +s2gos-client configure +``` + +Test: + +```bash +s2gos-client list-processes +``` + +## Development + +Install the S2GOS controller packages as described in +[Installation / Using GitHub](#using-github) above. + +## Linting and Testing + +To run all checks, execute + +```bash +pixi run checks +``` + +To run all tests, execute + +```bash +pixi run tests +``` + +To generate a coverage report, execute + +```bash +pixi run coverage +``` + +## Implementing Enhancements + +The S2GOS controller code relies heavily on the +[Eozilla](https://eo-tools.github.io/eozilla/) packages + +* [wraptile](https://github.com/eo-tools/eozilla/tree/main/wraptile), + which provides the gateway server implementation, +* [cuiman](https://github.com/eo-tools/eozilla/tree/main/cuiman), + which provides the client CLI, GUI, and API implementations, and +* [gavicore](https://github.com/eo-tools/eozilla/tree/main/gavicore) + which provides common OGC model classes and basic utilities. + +Should S2GOS controller require non-S2GOS-specific enhancements it +would likely be best to implement the required changes in the respective +Eozilla packages. For this, check out the Eozilla sources directly next +to this project's sources to achieve this folder structure: + +``` + / + ├── s2gos-controller/ + │ ├── s2gos-client/ + │ ├── s2gos-server/ + │ └── ... + └── eozilla/ + ├── appligator/ + ├── cuiman/ + ├── gavicore/ + ├── procodile/ + ├── wraptile/ + └── ... +``` + +For development, change the root `pyproject.toml` file as follows + +1. Comment out the dependencies `cuiman`, `gavicore`, etc. in the + `[tool.pixi.dependencies]` table. + +2. Uncomment the editable PyPI dependencies for `cuiman`, `gavicore`, etc. in + the `[tool.pixi.pypi-dependencies]` table. + +The run + +```bash +pixi i +``` + +to make the changes effective. Check with + +```bash +pixi ls +``` + +which should now list the Eozilla packages as editable. diff --git a/mkdocs.yml b/mkdocs.yml index 4f1625a..ddec47d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,6 +10,7 @@ copyright: Copyright © 2025 ESA DTE-S2GOS Team nav: - Overview: index.md + - Installation: installation.md - Architecture: architecture.md - Client CLI: client-cli.md - Client API: client-api.md diff --git a/pixi.lock b/pixi.lock index 598d237..dbb616c 100644 --- a/pixi.lock +++ b/pixi.lock @@ -13,6 +13,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-doc-0.0.4-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/appligator-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argcomplete-3.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda @@ -23,14 +24,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.1-h194c533_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.8-h346e085_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.5-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h7e655bb_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h7e655bb_8.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.6-h1deb5b9_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-had4b759_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.2-hbff472d_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-h8ba2272_8.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.8.6-h493c25d_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h7e655bb_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h7e655bb_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h7e655bb_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h7e655bb_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.0-h719b17a_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h522d481_6.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.1-h3a458e0_0.conda @@ -43,7 +44,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/backports.tarfile-1.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backrefs-5.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/black-25.1.0-py313h78bf25f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.2.0-h82add2a_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bokeh-3.8.1-pyhd8ed1ab_0.conda @@ -51,10 +52,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313h09d1b84_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda @@ -66,6 +67,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/crc32c-2.8-py313h54dd161_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-46.0.3-py313hafb0bba_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuiman-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cytoolz-1.1.0-py313h07c4f96_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2025.11.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.11.0-pyhcf101f3_0.conda @@ -90,6 +92,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/gavicore-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/genson-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_2.conda @@ -267,6 +270,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.8-unix_hf108a03_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/procodile-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.23.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda @@ -279,9 +283,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-22.0.0-py313he109ebe_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.4-pyh3cfb1c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.41.5-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.41.5-py313h843e2db_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.17.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-7.0.0-pyhcf101f3_1.conda @@ -308,7 +312,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-toolkit-0.15.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.28.0-py313h843e2db_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.28.0-py313h843e2db_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.14.4-h813ae00_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.6.0-h8399546_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/secretstorage-3.4.0-py313h78bf25f_0.conda @@ -316,13 +320,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/starlette-0.49.2-pyhfdc7a7d_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.2-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh0d859eb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda @@ -336,9 +340,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/traittypes-0.2.3-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2025.9.11.17-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.4.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhdb1f59b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h65a100f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhefaf540_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h4daf872_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda @@ -348,12 +352,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/userpath-1.9.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.9.8-h76e24b7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.9.9-h76e24b7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.38.0-pyh31011fe_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.38.0-h31011fe_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/uvloop-0.22.1-py313h07c4f96_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.35.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/watchdog-6.0.0-py313h78bf25f_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/watchdog-6.0.0-py313h78bf25f_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/watchfiles-1.1.1-py313h5c7d99a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.14-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda @@ -362,9 +366,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/websockets-15.0.1-py313h54dd161_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.15-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/wrapt-1.17.3-py313h07c4f96_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wraptile-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.10.1-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-3.1.3-pyhcf101f3_0.conda @@ -379,11 +384,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl - - pypi: ../eozilla/appligator - - pypi: ../eozilla/cuiman - - pypi: ../eozilla/gavicore - - pypi: ../eozilla/procodile - - pypi: ../eozilla/wraptile - pypi: ./s2gos-client - pypi: ./s2gos-server osx-64: @@ -391,6 +391,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-doc-0.0.4-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/appligator-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argcomplete-3.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda @@ -402,14 +403,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-auth-0.9.1-hd76a34f_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-cal-0.9.8-h6b06ba2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-common-0.12.5-h8616949_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-compression-0.3.1-h7df70e9_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-compression-0.3.1-h7df70e9_8.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-event-stream-0.5.6-h0ddc0d0_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-http-0.10.7-ha9fb31a_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-io-0.23.2-hccfe1ea_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-mqtt-0.13.3-ha2a017f_8.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-s3-0.8.6-hedfbfa3_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-sdkutils-0.2.4-h7df70e9_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-checksums-0.2.7-h7df70e9_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-sdkutils-0.2.4-h7df70e9_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-checksums-0.2.7-h7df70e9_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-crt-cpp-0.35.0-h7e7cb56_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aws-sdk-cpp-1.11.606-hf0dd41a_6.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/azure-core-cpp-1.16.1-he2a98a9_0.conda @@ -422,7 +423,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/backports.tarfile-1.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backrefs-5.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/black-25.1.0-py313habf4b1d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.2.0-h82add2a_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bokeh-3.8.1-pyhd8ed1ab_0.conda @@ -430,10 +431,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.2.0-py313hd4eab94_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.5-hf13058a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-2.0.0-py313hf57695f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda @@ -444,6 +445,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.11.3-py313h0f4d31d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/crc32c-2.8-py313hcb05632_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuiman-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cytoolz-1.1.0-py313hf050af9_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2025.11.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.11.0-pyhcf101f3_0.conda @@ -467,6 +469,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/gavicore-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/genson-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gflags-2.2.2-hac325c4_1005.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_2.conda @@ -634,6 +637,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.8-unix_hf108a03_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/procodile-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/prometheus-cpp-1.3.0-h7802330_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.23.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda @@ -646,9 +650,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-core-22.0.0-py313hff57800_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.4-pyh3cfb1c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.41.5-py313hcc225dc_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.41.5-py313hcc225dc_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.17.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-core-12.0-py313h07bcf3a_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-framework-cocoa-12.0-py313hf669bc3_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda @@ -677,19 +681,19 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-toolkit-0.15.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.28.0-py313hcc225dc_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.28.0-py313hcc225dc_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.14.4-hd9f4cfa_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh31c8845_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/snappy-1.2.2-h25c286d_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/snappy-1.2.2-h01f5ddf_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/starlette-0.49.2-pyhfdc7a7d_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.2-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh31c8845_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_2.conda @@ -703,9 +707,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/traittypes-0.2.3-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2025.9.11.17-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.4.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhdb1f59b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h65a100f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhefaf540_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h4daf872_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda @@ -715,12 +719,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/userpath-1.9.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/uv-0.9.8-h3315dae_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/uv-0.9.9-h3315dae_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.38.0-pyh31011fe_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.38.0-h31011fe_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/uvloop-0.22.1-py313hf050af9_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.35.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/watchdog-6.0.0-py313h585f44e_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/watchdog-6.0.0-py313hf050af9_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/watchfiles-1.1.1-py313ha265c4a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.14-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda @@ -729,9 +733,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/websockets-15.0.1-py313h6865ccc_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.15-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/wrapt-1.17.3-py313h585f44e_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wraptile-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.10.1-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-libxdmcp-1.1.5-h00291cd_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-libxdmcp-1.1.5-h8616949_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-3.1.3-pyhcf101f3_0.conda @@ -746,11 +751,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl - - pypi: ../eozilla/appligator - - pypi: ../eozilla/cuiman - - pypi: ../eozilla/gavicore - - pypi: ../eozilla/procodile - - pypi: ../eozilla/wraptile - pypi: ./s2gos-client - pypi: ./s2gos-server win-64: @@ -759,6 +759,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-doc-0.0.4-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.11.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/appligator-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argcomplete-3.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda @@ -769,14 +770,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.9.1-h179d6b4_5.conda - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.9.8-ha82e055_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.12.5-hfd05255_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.3.1-h83e01e5_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.3.1-h83e01e5_8.conda - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-event-stream-0.5.6-hd31a2bc_4.conda - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.10.7-h4b68edd_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.23.2-h460b297_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-mqtt-0.13.3-hfde8714_8.conda - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.8.6-haf2eb35_7.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.2.4-h83e01e5_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.2.7-h83e01e5_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.2.4-h83e01e5_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.2.7-h83e01e5_4.conda - conda: https://conda.anaconda.org/conda-forge/win-64/aws-crt-cpp-0.35.0-hd7c148e_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/aws-sdk-cpp-1.11.606-h2b076a5_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda @@ -792,10 +793,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313hf510273_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda - conda: https://conda.anaconda.org/conda-forge/win-64/c-ares-1.34.5-h2466b09_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-h4c7d964_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh7428d3b_0.conda @@ -806,6 +807,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.11.3-py313hd650c13_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda - conda: https://conda.anaconda.org/conda-forge/win-64/crc32c-2.8-py313h5fd188c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cuiman-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cytoolz-1.1.0-py313h5ea7bf4_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2025.11.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.11.0-pyhcf101f3_0.conda @@ -829,6 +831,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/gavicore-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/genson-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ghp-import-2.1.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.15.0-pyhd8ed1ab_0.conda @@ -987,6 +990,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.8-win_hba80fca_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/procodile-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.23.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.52-hd8ed1ab_0.conda @@ -998,9 +1002,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-core-22.0.0-py313h5921983_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.12.4-pyh3cfb1c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.41.5-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.41.5-py313hfbe8231_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.17.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-7.0.0-pyhcf101f3_1.conda @@ -1029,20 +1033,20 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-toolkit-0.15.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.28.0-py313hfbe8231_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.28.0-py313hfbe8231_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.14.4-h15e3a1f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh5737063_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/starlette-0.49.2-pyhfdc7a7d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-hd094cb3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.2-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh5737063_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda @@ -1056,9 +1060,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/traittypes-0.2.3-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2025.9.11.17-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.4.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhdb1f59b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h65a100f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhefaf540_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h4daf872_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda @@ -1069,7 +1073,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/userpath-1.9.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.9.8-h3bd95fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.9.9-h3bd95fe_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.38.0-pyh5737063_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-standard-0.38.0-h5737063_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_32.conda @@ -1077,7 +1081,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.35.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.44.35208-h38c0c73_32.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/watchdog-6.0.0-py313hfa70ccb_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/watchdog-6.0.0-py313hfa70ccb_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/watchfiles-1.1.1-py313hf61f64f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.14-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda @@ -1088,9 +1092,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/wrapt-1.17.3-py313h5ea7bf4_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wraptile-0.0.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.10.1-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-h0e40799_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-h0e40799_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-3.1.3-pyhcf101f3_0.conda @@ -1104,11 +1109,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl - - pypi: ../eozilla/appligator - - pypi: ../eozilla/cuiman - - pypi: ../eozilla/gavicore - - pypi: ../eozilla/procodile - - pypi: ../eozilla/wraptile - pypi: ./s2gos-client - pypi: ./s2gos-server packages: @@ -1198,7 +1198,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/anyio?source=hash-mapping + - pkg:pypi/anyio?source=compressed-mapping size: 138159 timestamp: 1758634638734 - pypi: https://files.pythonhosted.org/packages/53/c7/d168dd2e2120b1a61ffdcf6eaa6d992620a793d3bf7e12a59704eda1d83b/apache_airflow_client-3.0.2-py3-none-any.whl @@ -1210,18 +1210,21 @@ packages: - python-dateutil - urllib3>=2.1.0 requires_python: ~=3.9 -- pypi: ../eozilla/appligator - name: appligator - version: 0.0.8 - sha256: 02c0f3d145b3b7cec7bcc0e4efb1185ffeb9c6e5491e0603e2e4262c74e9f620 - requires_dist: +- conda: https://conda.anaconda.org/conda-forge/noarch/appligator-0.0.8-pyhd8ed1ab_0.conda + sha256: e49616e68e9b2ccbbac37ab67a2d3151544502f5795dc3dc003ba99a30d8b31b + md5: 08a7f7d3c61c0b590de41b1e65e9d041 + depends: + - gavicore >=0.0.7 + - procodile >=0.0.7 - pydantic + - python >=3.10 - pyyaml - typer - - gavicore>=0.0.7 - - procodile>=0.0.7 - requires_python: '>=3.10' - editable: true + license: Apache-2.0 + purls: + - pkg:pypi/appligator?source=hash-mapping + size: 16020 + timestamp: 1762858580072 - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda sha256: 8f032b140ea4159806e4969a68b4a3c0a7cab1ad936eb958a2b5ffe5335e19bf md5: 54898d0f524c9dee622d44bbb081a8ab @@ -1315,7 +1318,7 @@ packages: license: Apache-2.0 license_family: APACHE purls: - - pkg:pypi/arrow?source=hash-mapping + - pkg:pypi/arrow?source=compressed-mapping size: 113854 timestamp: 1760831179410 - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.0-pyhd8ed1ab_1.conda @@ -1476,32 +1479,30 @@ packages: purls: [] size: 236775 timestamp: 1762858573513 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h7e655bb_7.conda - sha256: 4bb712dc47f85e0270362fde51ce953803dd2d06526cfb5e56181ec571dcf496 - md5: f175411b6b88db33d1529f7fac572070 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h7e655bb_8.conda + sha256: e91d2fc0fddf069b8d39c0ce03eca834673702f7e17eda8e7ffc4558b948053d + md5: 1baf55dfcc138d98d437309e9aba2635 depends: - libgcc >=14 - __glibc >=2.17,<3.0.a0 - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 - license_family: APACHE purls: [] - size: 22117 - timestamp: 1761044126699 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-compression-0.3.1-h7df70e9_7.conda - sha256: 9f29b2ca99fd79fdb4fe29ce511431bac708d01b85b10fdade7046339306c0e6 - md5: 6856da211592fa6571a48425f9496068 + size: 22138 + timestamp: 1762957433991 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-compression-0.3.1-h7df70e9_8.conda + sha256: b1039b7f3b7a30622c8ce10545ab568653a656ffb56776292a56d8e2b560af06 + md5: e80fc40b09b24a964df1a27d76162a4f depends: - __osx >=10.13 - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 - license_family: APACHE purls: [] - size: 21119 - timestamp: 1761044164764 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.3.1-h83e01e5_7.conda - sha256: d5b71f45edccb3639e2edb8711e0c36bbf32e90e47c16f2715d34cfc155e5b5a - md5: 7112c407057a09c3917d0f6c587a4e4c + size: 21163 + timestamp: 1762957488953 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.3.1-h83e01e5_8.conda + sha256: ef7265145a1afe41bf4676f08634e76918afb6fad3bc934bdec02f90d1908eba + md5: c531103556862e44ba19003638b72fb0 depends: - vc >=14.3,<15 - vc14_runtime >=14.44.35208 @@ -1511,10 +1512,9 @@ packages: - ucrt >=10.0.20348.0 - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 - license_family: APACHE purls: [] - size: 23116 - timestamp: 1761044168058 + size: 23132 + timestamp: 1762957485681 - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.6-h1deb5b9_4.conda sha256: ed5131ac1f3f380b2a9f2035a4947e6d96e110bc3d4e24ca12f620e2e861fb07 md5: 61939d0173b83ed26953e30b5cb37322 @@ -1753,32 +1753,30 @@ packages: purls: [] size: 129128 timestamp: 1762250017226 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h7e655bb_2.conda - sha256: 92afcb2bdd1be01c929afc3b1bd05f87a987e3ca31fdec66045b3ed257f7d18a - md5: c82741cfa2c26c27e600694fdf47aa37 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h7e655bb_3.conda + sha256: 8d84039ea1d33021623916edfc23f063a5bcef90e8f63ae7389e1435deb83e53 + md5: 70e83d2429b7edb595355316927dfbea depends: - - libgcc >=14 - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 - license_family: APACHE purls: [] - size: 59082 - timestamp: 1761045751420 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-sdkutils-0.2.4-h7df70e9_2.conda - sha256: dfa0dc788fb808609eda0b5b139b7c53762ea1500e0c2d6b7626da6a67b2e7e7 - md5: 6143bef47cb2a462ac8c59c7345f4a8f + size: 59204 + timestamp: 1762957305800 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-c-sdkutils-0.2.4-h7df70e9_3.conda + sha256: 65b2a085fc7cbb42a8b2ffc4b7b1e62b942a22cf82bfced2b042b42b8b7b1fc5 + md5: 542b06622aa7982c2109b175bd97c20a depends: - __osx >=10.13 - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 - license_family: APACHE purls: [] - size: 55372 - timestamp: 1761046213127 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.2.4-h83e01e5_2.conda - sha256: 66baf285c73ac8f16bd5de4c13f1913dc13a5d8ecf7fc97ed88453d319b0e606 - md5: ac3bdeb8a01e6a4900cf7e9907dc63f2 + size: 55413 + timestamp: 1762957350211 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.2.4-h83e01e5_3.conda + sha256: 098b17697f392ed3253754f4a5c776b422a89489834bfc7b8593ac46294820e4 + md5: 1860dd0926b5eb0fcb19b581b908975b depends: - vc >=14.3,<15 - vc14_runtime >=14.44.35208 @@ -1788,36 +1786,33 @@ packages: - ucrt >=10.0.20348.0 - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 - license_family: APACHE purls: [] - size: 56441 - timestamp: 1761045782615 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h7e655bb_3.conda - sha256: 65255f3c35f0a22714d13ef4ba91b897fefa1ff7feac3440adc4c9e7715315b5 - md5: 44f8b6b21db8318f1743a28049df4695 + size: 56482 + timestamp: 1762957352222 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h7e655bb_4.conda + sha256: a95b3cc8e3c0ddb664bbd26333b35986fd406f02c2c60d380833751d2d9393bd + md5: 83a6e0fc73a7f18a8024fc89455da81c depends: - - __glibc >=2.17,<3.0.a0 - libgcc >=14 + - __glibc >=2.17,<3.0.a0 - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 - license_family: APACHE purls: [] - size: 76790 - timestamp: 1761044208107 -- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-checksums-0.2.7-h7df70e9_3.conda - sha256: 2e0f7e673bda75eaf5670184341fd9baed18fa49b5dcc30c129720bfde65214e - md5: 16741d8bb4a553a20fbd348ae1c24d13 + size: 76774 + timestamp: 1762957236884 +- conda: https://conda.anaconda.org/conda-forge/osx-64/aws-checksums-0.2.7-h7df70e9_4.conda + sha256: 3361ffbe6cc8f65d6e9ad59a6df97810f37a062276a3742ac3159f54c9e50b0c + md5: def63445d08ca87ffd5640123b1251a9 depends: - __osx >=10.13 - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 - license_family: APACHE purls: [] - size: 75345 - timestamp: 1761044272151 -- conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.2.7-h83e01e5_3.conda - sha256: d839e97bbab4401dfedaf14df9f6b85437aec764ec930ba37c6934aea42c9182 - md5: 5d04b017f6431cb9742c8629f9e72ebc + size: 75344 + timestamp: 1762957255006 +- conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.2.7-h83e01e5_4.conda + sha256: 5112b8809adc01dbd77910514a0bcda87dd7fb74519e9d85beb07d32111706de + md5: 789551227529bc1c3ef3cbd1a2a1f5e4 depends: - vc >=14.3,<15 - vc14_runtime >=14.44.35208 @@ -1827,10 +1822,9 @@ packages: - ucrt >=10.0.20348.0 - aws-c-common >=0.12.5,<0.12.6.0a0 license: Apache-2.0 - license_family: APACHE purls: [] - size: 93126 - timestamp: 1761044244040 + size: 93120 + timestamp: 1762957265474 - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.0-h719b17a_2.conda sha256: d34850625fdcbaeda37fd3b83446b71e925463ec79d15ba430636c19526116ed md5: 2e313660820653ba7557ccbe235b402a @@ -2149,39 +2143,39 @@ packages: - pkg:pypi/beautifulsoup4?source=hash-mapping size: 89146 timestamp: 1759146127397 -- conda: https://conda.anaconda.org/conda-forge/linux-64/black-25.1.0-py313h78bf25f_0.conda - sha256: f6b6e2e529fbac828c9cb630f09333a66749dab5291aa067407ba2593689d2d7 - md5: 9ea587916fdf7b23e723e428f02c1bb5 +- conda: https://conda.anaconda.org/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda + sha256: c68f110cd491dc839a69e340930862e54c00fb02cede5f1831fcf8a253bd68d2 + md5: b9b0c42e7316aa6043bdfd49883955b8 depends: - click >=8.0.0 - mypy_extensions >=0.4.3 - packaging >=22.0 - pathspec >=0.9 - platformdirs >=2 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python >=3.11 license: MIT license_family: MIT purls: - pkg:pypi/black?source=hash-mapping - size: 398823 - timestamp: 1738616111923 -- conda: https://conda.anaconda.org/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda - sha256: c68f110cd491dc839a69e340930862e54c00fb02cede5f1831fcf8a253bd68d2 - md5: b9b0c42e7316aa6043bdfd49883955b8 + size: 172678 + timestamp: 1742502887437 +- conda: https://conda.anaconda.org/conda-forge/osx-64/black-25.1.0-py313habf4b1d_0.conda + sha256: 293c0048448eec702c58f12aa7ccab71102e5e61482d3ad6439208ab4d7b5ada + md5: c4f8ef5281c64a0f15ec659e51bb079f depends: - click >=8.0.0 - mypy_extensions >=0.4.3 - packaging >=22.0 - pathspec >=0.9 - platformdirs >=2 - - python >=3.11 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 license: MIT license_family: MIT purls: - pkg:pypi/black?source=hash-mapping - size: 172678 - timestamp: 1742502887437 + size: 401564 + timestamp: 1738616279268 - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda sha256: a05971bb80cca50ce9977aad3f7fc053e54ea7d5321523efc7b9a6e12901d3cd md5: f0b4c8e370446ef89797608d60a564b3 @@ -2355,24 +2349,24 @@ packages: purls: [] size: 194147 timestamp: 1744128507613 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-h4c7d964_0.conda - sha256: bfb7f9f242f441fdcd80f1199edd2ecf09acea0f2bcef6f07d7cbb1a8131a345 - md5: e54200a1cd1fe33d61c9df8d3b00b743 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-h4c7d964_0.conda + sha256: 686a13bd2d4024fc99a22c1e0e68a7356af3ed3304a8d3ff6bb56249ad4e82f0 + md5: f98fb7db808b94bc1ec5b0e62f9f1069 depends: - __win license: ISC purls: [] - size: 156354 - timestamp: 1759649104842 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda - sha256: 3b5ad78b8bb61b6cdc0978a6a99f8dfb2cc789a451378d054698441005ecbdb6 - md5: f9e5fbc24009179e8b0409624691758a + size: 152827 + timestamp: 1762967310929 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda + sha256: b986ba796d42c9d3265602bc038f6f5264095702dd546c14bc684e60c385e773 + md5: f0991f0f84902f6b6009b4d2350a83aa depends: - __unix license: ISC purls: [] - size: 155907 - timestamp: 1759649036195 + size: 152432 + timestamp: 1762967197890 - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 noarch: python sha256: 561e6660f26c35d137ee150187d89767c988413c978e1b712d53f27ddf70ea17 @@ -2395,16 +2389,16 @@ packages: - pkg:pypi/cached-property?source=hash-mapping size: 11065 timestamp: 1615209567874 -- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda - sha256: 955bac31be82592093f6bc006e09822cd13daf52b28643c9a6abd38cd5f4a306 - md5: 257ae203f1d204107ba389607d375ded +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda + sha256: 083a2bdad892ccf02b352ecab38ee86c3e610ba9a4b11b073ea769d55a115d32 + md5: 96a02a5c1a65470a7e4eedb644c872fd depends: - python >=3.10 license: ISC purls: - - pkg:pypi/certifi?source=hash-mapping - size: 160248 - timestamp: 1759648987029 + - pkg:pypi/certifi?source=compressed-mapping + size: 157131 + timestamp: 1762976260320 - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda sha256: 2162a91819945c826c6ef5efe379e88b1df0fe9a387eeba23ddcf7ebeacd5bd6 md5: d0616e7935acab407d1543b28c446f6f @@ -2679,21 +2673,24 @@ packages: - pkg:pypi/cryptography?source=hash-mapping size: 1718808 timestamp: 1760605188769 -- pypi: ../eozilla/cuiman - name: cuiman - version: 0.0.8 - sha256: 871aaa2a3816d3e4ff13bdf7b7a8e1350334cc4c9c31b24e4d1e9df2831e80f4 - requires_dist: +- conda: https://conda.anaconda.org/conda-forge/noarch/cuiman-0.0.8-pyhd8ed1ab_0.conda + sha256: 6a16d0d79f2bda1abc8e64dfb479ed571c673327427f4fc20ef19702bd279be6 + md5: b1a872de1a3d99b31af82bbfbde69994 + depends: - click + - gavicore >=0.0.7 + - httpx - panel - pydantic + - python >=3.10 - pyyaml - typer - uri-template - - httpx - - gavicore>=0.0.7 - requires_python: '>=3.10' - editable: true + license: Apache-2.0 + purls: + - pkg:pypi/cuiman?source=hash-mapping + size: 37456 + timestamp: 1762852263498 - conda: https://conda.anaconda.org/conda-forge/linux-64/cytoolz-1.1.0-py313h07c4f96_1.conda sha256: a8ffc7cf31a698a57a46bf7977185ed1e644c5e35d4e166d8f260dca93af6ffb md5: bcca9afd203fe05d9582249ac12762da @@ -3115,19 +3112,21 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/fsspec?source=hash-mapping + - pkg:pypi/fsspec?source=compressed-mapping size: 146592 timestamp: 1761840236679 -- pypi: ../eozilla/gavicore - name: gavicore - version: 0.0.8 - sha256: 488145ac6c86f4b19f5169523deab4ab235b1edb34422b14242df95c6e9e91e6 - requires_dist: - - click +- conda: https://conda.anaconda.org/conda-forge/noarch/gavicore-0.0.8-pyhd8ed1ab_0.conda + sha256: ebc079e560afae146f8e77f1003cd0beb88120f181669dea2d633cc14ada16dc + md5: 1e98a8762d387f6ec852d6093258ddc7 + depends: - pydantic + - python >=3.10 - typer - requires_python: '>=3.10' - editable: true + license: Apache-2.0 + purls: + - pkg:pypi/gavicore?source=hash-mapping + size: 24205 + timestamp: 1762851993862 - conda: https://conda.anaconda.org/conda-forge/noarch/genson-1.3.0-pyhd8ed1ab_0.conda sha256: 2b9e4e8321e355bb8792ccf7722b81e481f3f664d145ad4b851a66ebac2d9c71 md5: d3c12a70d5dc21f05647a80f72a81aa1 @@ -3407,7 +3406,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/idna?source=hash-mapping + - pkg:pypi/idna?source=compressed-mapping size: 50721 timestamp: 1760286526795 - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda @@ -4081,7 +4080,7 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyterlab-server?source=hash-mapping + - pkg:pypi/jupyterlab-server?source=compressed-mapping size: 51621 timestamp: 1761145478692 - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.16-pyhcf101f3_1.conda @@ -7970,17 +7969,20 @@ packages: - pkg:pypi/pluggy?source=hash-mapping size: 24246 timestamp: 1747339794916 -- pypi: ../eozilla/procodile - name: procodile - version: 0.0.8 - sha256: 761ceddd0d3ac3b5717e1fa18c73ac7f949c2fd57e621dde38e721aea31d589b - requires_dist: +- conda: https://conda.anaconda.org/conda-forge/noarch/procodile-0.0.8-pyhd8ed1ab_0.conda + sha256: 57958b69b8ed1850ec7cb4a4271a806c1a083090afffffd14401b9d7f313aa1f + md5: 180b22c3b9914cfdd7cc914f1b54f41c + depends: + - gavicore >=0.0.7 - pydantic + - python >=3.10 - pyyaml - typer - - gavicore>=0.0.7 - requires_python: '>=3.10' - editable: true + license: Apache-2.0 + purls: + - pkg:pypi/procodile?source=hash-mapping + size: 22993 + timestamp: 1762852066423 - conda: https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda sha256: 013669433eb447548f21c3c6b16b2ed64356f726b5f77c1b39d5ba17a8a4b8bc md5: a83f6a2fdc079e643237887a37460668 @@ -8282,9 +8284,9 @@ packages: - pkg:pypi/pydantic?source=hash-mapping size: 320446 timestamp: 1762379584494 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.41.5-py313h843e2db_0.conda - sha256: ef873b022656313991ec6e07ad1708e64b7d712de896b1907bd091dfe453b1e0 - md5: b7ecbb230837ea4f4f60227dc8b491b7 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.41.5-py313h843e2db_1.conda + sha256: b15568ddc03bd33ea41610e5df951be4e245cd61957cbf8c2cfd12557f3d53b5 + md5: f27c39a1906771bbe56cd26a76bf0b8b depends: - python - typing-extensions >=4.6.0,!=4.7.0 @@ -8294,14 +8296,13 @@ packages: constrains: - __glibc >=2.17 license: MIT - license_family: MIT purls: - pkg:pypi/pydantic-core?source=hash-mapping - size: 1944972 - timestamp: 1762358832380 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.41.5-py313hcc225dc_0.conda - sha256: 7b200b234685a0b4d89ac42c0fcdc41ecbd5396a5940f878bfd223eaf624ba6d - md5: 0ad0de3b4c48fc12c036361347854b00 + size: 1940186 + timestamp: 1762989000579 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.41.5-py313hcc225dc_1.conda + sha256: 73de35081774d9b445dd807ac4d4e043846159b2de348b8e6a81f1b810210fe4 + md5: e12491c39d2ea259771ce4d80a91817f depends: - python - typing-extensions >=4.6.0,!=4.7.0 @@ -8310,14 +8311,13 @@ packages: constrains: - __osx >=10.13 license: MIT - license_family: MIT purls: - - pkg:pypi/pydantic-core?source=hash-mapping - size: 1951438 - timestamp: 1762358861637 -- conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.41.5-py313hfbe8231_0.conda - sha256: 82ee80cb7272551031d7e8a42494ce3d67897288605bcb76269c995ea8aa69fc - md5: 639e9460fc15dce7b0eed455c84d6c8d + - pkg:pypi/pydantic-core?source=compressed-mapping + size: 1947011 + timestamp: 1762989008917 +- conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.41.5-py313hfbe8231_1.conda + sha256: fb9391dc09dd01574c85e2342b9aa3b8664cd713401ef8fd6267865cc28988d8 + md5: 0437f87004ad7c64c98a013d1611db97 depends: - python - typing-extensions >=4.6.0,!=4.7.0 @@ -8329,11 +8329,10 @@ packages: - ucrt >=10.0.20348.0 - python_abi 3.13.* *_cp313 license: MIT - license_family: MIT purls: - - pkg:pypi/pydantic-core?source=hash-mapping - size: 1976270 - timestamp: 1762358914181 + - pkg:pypi/pydantic-core?source=compressed-mapping + size: 1973031 + timestamp: 1762989056610 - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a md5: 6b6ece66ebcae2d5f326c77ef2c5a066 @@ -8345,19 +8344,19 @@ packages: - pkg:pypi/pygments?source=hash-mapping size: 889287 timestamp: 1750615908735 -- conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda - sha256: 8f575f123694e5acd2829440da55828f2cea60b0af5d8fa5406d83251ba80f61 - md5: 26e013bc453e643991cfa9b76911fb79 +- conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.17.1-pyhd8ed1ab_0.conda + sha256: e96cc6221542c8d70b0f5d57970616f61944af02ddc161a5f255c919c1ff7867 + md5: ba4e2779714fb70737ec9938c74b4672 depends: - markdown >=3.6 - - python >=3.9 + - python >=3.10 - pyyaml license: MIT license_family: MIT purls: - pkg:pypi/pymdown-extensions?source=hash-mapping - size: 170121 - timestamp: 1753743741894 + size: 169949 + timestamp: 1762988007623 - conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-core-12.0-py313h07bcf3a_2.conda sha256: db216f3c43a955a056173eca2baa8ecbfa3fa3d67ecfbcdead9c90be031b560c md5: 71fd34f70212d4e0cc435aa441148128 @@ -8370,7 +8369,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/pyobjc-core?source=hash-mapping + - pkg:pypi/pyobjc-core?source=compressed-mapping size: 489967 timestamp: 1762461057373 - conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-framework-cocoa-12.0-py313hf669bc3_2.conda @@ -8444,7 +8443,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/pytest-cov?source=hash-mapping + - pkg:pypi/pytest-cov?source=compressed-mapping size: 29016 timestamp: 1757612051022 - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda @@ -8696,7 +8695,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/pyyaml?source=compressed-mapping + - pkg:pypi/pyyaml?source=hash-mapping size: 207109 timestamp: 1758892173548 - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.3-py313h0f4d31d_0.conda @@ -8877,7 +8876,7 @@ packages: license: Apache-2.0 license_family: APACHE purls: - - pkg:pypi/requests?source=hash-mapping + - pkg:pypi/requests?source=compressed-mapping size: 59263 timestamp: 1755614348400 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda @@ -8946,25 +8945,24 @@ packages: - pkg:pypi/rich-toolkit?source=hash-mapping size: 29432 timestamp: 1756998936181 -- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.28.0-py313h843e2db_1.conda - sha256: d0bcf40c20b4c4921b0c244b2ae1a9188f511cdeff5974602900257d7aa2ee0c - md5: b4e5c52948b191bfb04da5788217afdb +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.28.0-py313h843e2db_2.conda + sha256: a324240a742bd109fa97661916823e6c2d45b4c6f58957225c914a06cf863794 + md5: 60c24f26f922abfc661967b0ef609935 depends: - python - - libgcc >=14 - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - python_abi 3.13.* *_cp313 constrains: - __glibc >=2.17 license: MIT - license_family: MIT purls: - pkg:pypi/rpds-py?source=hash-mapping - size: 380486 - timestamp: 1761178917553 -- conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.28.0-py313hcc225dc_1.conda - sha256: 5b6c6579188626f0a9d392218c72b6608739542192f8288b6f66c53fccbb4913 - md5: 3d246461e113f0dc3e992f256dda09a0 + size: 379483 + timestamp: 1762984685444 +- conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.28.0-py313hcc225dc_2.conda + sha256: de42fe92e48489db088100cd9a7f13b3704cb6d7fc17998d7c4835b347a893ba + md5: 0503a15e19cfbb953fc7d20eda379b5a depends: - python - __osx >=10.13 @@ -8972,14 +8970,13 @@ packages: constrains: - __osx >=10.13 license: MIT - license_family: MIT purls: - pkg:pypi/rpds-py?source=hash-mapping - size: 366957 - timestamp: 1761178597606 -- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.28.0-py313hfbe8231_1.conda - sha256: 98a042a41e9c14b3500b560d3cc83ad4d05180dc1bbfadb9e416826016b4649e - md5: b78312a5f81f1a7f20cabc5efe5b15ce + size: 366992 + timestamp: 1762984648624 +- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.28.0-py313hfbe8231_2.conda + sha256: 015fd789b92c04c8d2014a38f260bef28ad14509f8988a89cc4ec1a59ee0cd10 + md5: 169a0b7ee5dcf603511595e00c395f5e depends: - python - vc >=14.3,<15 @@ -8990,11 +8987,10 @@ packages: - ucrt >=10.0.20348.0 - python_abi 3.13.* *_cp313 license: MIT - license_family: MIT purls: - pkg:pypi/rpds-py?source=hash-mapping - size: 240192 - timestamp: 1761178419906 + size: 238558 + timestamp: 1762984540101 - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.14.4-h813ae00_0.conda noarch: python sha256: 23121b3e5d6f0cfe8cf6600a2b1e63e4f8cdd3aa2ceee25625b98a3caa2d93e5 @@ -9154,33 +9150,31 @@ packages: - pkg:pypi/six?source=hash-mapping size: 18455 timestamp: 1753199211006 -- conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_0.conda - sha256: 8b8acbde6814d1643da509e11afeb6bb30eb1e3004cf04a7c9ae43e9b097f063 - md5: 3d8da0248bdae970b4ade636a104b7f5 +- conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda + sha256: 48f3f6a76c34b2cfe80de9ce7f2283ecb55d5ed47367ba91e8bb8104e12b8f11 + md5: 98b6c9dc80eb87b2519b97bcf7e578dd depends: - libgcc >=14 + - __glibc >=2.17,<3.0.a0 - libstdcxx >=14 - libgcc >=14 - - __glibc >=2.17,<3.0.a0 license: BSD-3-Clause - license_family: BSD purls: [] - size: 45805 - timestamp: 1753083455352 -- conda: https://conda.anaconda.org/conda-forge/osx-64/snappy-1.2.2-h25c286d_0.conda - sha256: e9ccbdbfaa9abd21636decd524d9845dee5a67af593b1d54525a48f2b03d3d76 - md5: e6544ab8824f58ca155a5b8225f0c780 + size: 45829 + timestamp: 1762948049098 +- conda: https://conda.anaconda.org/conda-forge/osx-64/snappy-1.2.2-h01f5ddf_1.conda + sha256: 1525e6d8e2edf32dabfe2a8e2fc8bf2df81c5ef9f0b5374a3d4ccfa672bfd949 + md5: 2e993292ec18af5cd480932d448598cf depends: - libcxx >=19 - __osx >=10.13 license: BSD-3-Clause - license_family: BSD purls: [] - size: 39975 - timestamp: 1753083485577 -- conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_0.conda - sha256: b38ed597bf71f73275a192b8cb22888997760bac826321f5838951d5d31acb23 - md5: 194a0c548899fa2a10684c34e56a3564 + size: 40023 + timestamp: 1762948053450 +- conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_1.conda + sha256: d2deda1350abf8c05978b73cf7fe9147dd5c7f2f9b312692d1b98e52efad53c3 + md5: 3075846de68f942150069d4289aaad63 depends: - vc >=14.3,<15 - vc14_runtime >=14.44.35208 @@ -9189,21 +9183,20 @@ packages: - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 license: BSD-3-Clause - license_family: BSD purls: [] - size: 67221 - timestamp: 1753083479147 -- conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_1.conda - sha256: c2248418c310bdd1719b186796ae50a8a77ce555228b6acd32768e2543a15012 - md5: bf7a226e58dfb8346c70df36065d86c9 + size: 67417 + timestamp: 1762948090450 +- conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + sha256: dce518f45e24cd03f401cb0616917773159a210c19d601c5f2d4e0e5879d30ad + md5: 03fe290994c5e4ec17293cfb6bdce520 depends: - - python >=3.9 + - python >=3.10 license: Apache-2.0 license_family: Apache purls: - - pkg:pypi/sniffio?source=hash-mapping - size: 15019 - timestamp: 1733244175724 + - pkg:pypi/sniffio?source=compressed-mapping + size: 15698 + timestamp: 1762941572482 - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda sha256: d1e3e06b5cf26093047e63c8cc77b70d970411c5cbc0cb1fad461a8a8df599f7 md5: 0401a17ae845fa72c7210e206ec5647d @@ -9266,17 +9259,17 @@ packages: purls: [] size: 155714 timestamp: 1762510341121 -- conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.1-pyhcf101f3_0.conda - sha256: 60c58dca39b30c3d1e2d8a474fe71c04537b8a5e42b9759706129f36100c84bf - md5: c07c341cc6ab9ed17b5a087e4bc954d0 +- conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.2.2-pyhcf101f3_0.conda + sha256: 6b549360f687ee4d11bf85a6d6a276a30f9333df1857adb0fe785f0f8e9bcd60 + md5: f88bb644823094f436792f80fba3207e depends: - python >=3.10 - python license: BSD-2-Clause purls: - pkg:pypi/tblib?source=hash-mapping - size: 19264 - timestamp: 1762444129641 + size: 19397 + timestamp: 1762956379123 - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh0d859eb_0.conda sha256: b300557c0382478cf661ddb520263508e4b3b5871b471410450ef2846e8c352c md5: efba281bbdae5f6b0a1d53c6d4a97c93 @@ -9514,22 +9507,21 @@ packages: - pkg:pypi/typeguard?source=hash-mapping size: 35158 timestamp: 1750249264892 -- conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhdb1f59b_0.conda - sha256: e4708f3f7f72e92511b1f6defca8cac520cef1af3cda92c3b7901731f7ddcb75 - md5: 27ec7c3f99366fa64228c3ee4ab49cbc +- conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.20.0-pyhefaf540_1.conda + sha256: 17a1e572939af33d709248170871d4da74f7e32b48f2e9b5abca613e201c6e64 + md5: 23a53fdefc45ba3f4e075cc0997fd13b depends: - - typer-slim-standard ==0.20.0 h65a100f_0 + - typer-slim-standard ==0.20.0 h4daf872_1 - python >=3.10 - python license: MIT - license_family: MIT purls: - - pkg:pypi/typer?source=hash-mapping - size: 79367 - timestamp: 1760982314002 -- conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_0.conda - sha256: 08904a433b7ab6b2e0267576043a8397bb3ce7296d71aef34ae7d2506b2c192a - md5: d8ad446a00bbd434d6d03cdcc9b46524 + - pkg:pypi/typer?source=compressed-mapping + size: 79829 + timestamp: 1762984042927 +- conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.20.0-pyhcf101f3_1.conda + sha256: 4b5ded929080b91367f128e7299619f6116f08bc77d9924a2f8766e2a1b18161 + md5: 4b02a515f3e882dcfe9cfbf0a1f5cd3a depends: - python >=3.10 - click >=8.0.0 @@ -9540,23 +9532,21 @@ packages: - rich >=10.11.0 - shellingham >=1.3.0 license: MIT - license_family: MIT purls: - - pkg:pypi/typer-slim?source=hash-mapping - size: 47419 - timestamp: 1760982313997 -- conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h65a100f_0.conda - sha256: a4726dec9ec806757f5f0fee65f54f790d3f4854a869bd4cd2c2805c54b52d37 - md5: cfd4be2a44e441b12b58a7d04c9434e9 + - pkg:pypi/typer-slim?source=compressed-mapping + size: 47951 + timestamp: 1762984042920 +- conda: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.20.0-h4daf872_1.conda + sha256: 5027768bc9a580c8ffbf25872bb2208c058cbb79ae959b1cf2cc54b5d32c0377 + md5: 37b26aafb15a6687b31a3d8d7a1f04e7 depends: - - typer-slim ==0.20.0 pyhcf101f3_0 + - typer-slim ==0.20.0 pyhcf101f3_1 - rich - shellingham license: MIT - license_family: MIT purls: [] - size: 5294 - timestamp: 1760982314002 + size: 5322 + timestamp: 1762984042927 - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c md5: edd329d7d3a4ab45dcf905899a7a6115 @@ -9668,9 +9658,9 @@ packages: - pkg:pypi/userpath?source=hash-mapping size: 14292 timestamp: 1735925027874 -- conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.9.8-h76e24b7_0.conda - sha256: 3a0fdfb99e3c2e228991b078ff4495cb8462db589b8c00be32baa60d24306fb2 - md5: 23b31dda4cca5794d1cceb0f9faa3238 +- conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.9.9-h76e24b7_0.conda + sha256: 2e20f8c6e69374688cf8177a280b199c9c92161bf22465071f81832a3074f003 + md5: bc71e01e6f7abacff84011d596cb58d3 depends: - libgcc >=14 - libstdcxx >=14 @@ -9680,11 +9670,11 @@ packages: - __glibc >=2.17 license: Apache-2.0 OR MIT purls: [] - size: 17103477 - timestamp: 1762567870164 -- conda: https://conda.anaconda.org/conda-forge/osx-64/uv-0.9.8-h3315dae_0.conda - sha256: cc4c6245625ec973cabf76df7ace411da20565dc0d22fc18a46dde0ba3447d20 - md5: e470fc798df77c27b4d8df24336a3e58 + size: 16822208 + timestamp: 1762997132411 +- conda: https://conda.anaconda.org/conda-forge/osx-64/uv-0.9.9-h3315dae_0.conda + sha256: 5681a5fb637baa1c01f60d7a028b226133719d54be0d78202e2aa17ad6114b3f + md5: 7829a81ebbb5a1b76fe854fd9693e74e depends: - libcxx >=19 - __osx >=10.13 @@ -9692,11 +9682,11 @@ packages: - __osx >=10.13 license: Apache-2.0 OR MIT purls: [] - size: 15989903 - timestamp: 1762567632356 -- conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.9.8-h3bd95fe_0.conda - sha256: 4c58c598763bb67846433faa840a8b67900fd94bee21b20ab1de190aa689821d - md5: f1daf65eb0cf5b52daccc7942920708e + size: 15736437 + timestamp: 1762997071560 +- conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.9.9-h3bd95fe_0.conda + sha256: f8e494c8503ada66a42b7a91f564cd616bcd5b542bcf64bc88d2f235a827ab81 + md5: 14d4520f123e40ea6725c52e5f473f95 depends: - vc >=14.3,<15 - vc14_runtime >=14.44.35208 @@ -9706,8 +9696,8 @@ packages: - ucrt >=10.0.20348.0 license: Apache-2.0 OR MIT purls: [] - size: 17336615 - timestamp: 1762567488942 + size: 17495993 + timestamp: 1762996907985 - conda: https://conda.anaconda.org/conda-forge/noarch/uvicorn-0.38.0-pyh31011fe_0.conda sha256: 32e637726fd7cfeb74058e829b116e17514d001846fef56d8c763ec9ec5ac887 md5: d3aa78bc38d9478e9eed5f128ba35f41 @@ -9861,46 +9851,43 @@ packages: purls: [] size: 18919 timestamp: 1760418632059 -- conda: https://conda.anaconda.org/conda-forge/linux-64/watchdog-6.0.0-py313h78bf25f_1.conda - sha256: 73225611a442fdebc9d333951037a428f6e9b8449d4194030457c026970a3283 - md5: d643d87d7df61d3d47db87bdd4571ec6 +- conda: https://conda.anaconda.org/conda-forge/linux-64/watchdog-6.0.0-py313h78bf25f_2.conda + sha256: 2ac9fa6fe7f771244dda964485617be55e7d3329da1347b22efb911700eea5cc + md5: 283321e8f46f8102ee3b5d1c282ff0fa depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - pyyaml >=3.10 license: Apache-2.0 - license_family: APACHE purls: - - pkg:pypi/watchdog?source=hash-mapping - size: 144014 - timestamp: 1756135338277 -- conda: https://conda.anaconda.org/conda-forge/osx-64/watchdog-6.0.0-py313h585f44e_1.conda - sha256: 63961c1cac16f0f2dbb32f2499b16d59895a4727df7afae2c61e1c91f083e048 - md5: f9f9ec9a5a54a9b2a8cf8891fe934be5 + - pkg:pypi/watchdog?source=compressed-mapping + size: 144332 + timestamp: 1763021754141 +- conda: https://conda.anaconda.org/conda-forge/osx-64/watchdog-6.0.0-py313hf050af9_2.conda + sha256: 38d3595b560c74635acedc7c0300042d155640f8dccc2ba096cd98f57a217538 + md5: ea12d2a212ac4010892006a339e9d35d depends: - __osx >=10.13 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - pyyaml >=3.10 license: Apache-2.0 - license_family: APACHE purls: - pkg:pypi/watchdog?source=hash-mapping - size: 151558 - timestamp: 1756135500585 -- conda: https://conda.anaconda.org/conda-forge/win-64/watchdog-6.0.0-py313hfa70ccb_1.conda - sha256: 06263427dcd0100706d26c0461f2ff8356f23f4b2ee047f67d0cd7f073e2c842 - md5: ff8bfc0c2479faccdfa9ec9859ed663b + size: 151391 + timestamp: 1763022338658 +- conda: https://conda.anaconda.org/conda-forge/win-64/watchdog-6.0.0-py313hfa70ccb_2.conda + sha256: fede6e7ed557aa8290973ceda605b29dffec01c8a97ee6bd1e52ad02b897906f + md5: ce01d1bdf4558aee247efb613ff77e2a depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - pyyaml >=3.10 license: Apache-2.0 - license_family: APACHE purls: - pkg:pypi/watchdog?source=hash-mapping - size: 168440 - timestamp: 1756135584322 + size: 169318 + timestamp: 1763021892678 - conda: https://conda.anaconda.org/conda-forge/linux-64/watchfiles-1.1.1-py313h5c7d99a_0.conda sha256: 11a07764137af9bcf29e9e26671c1be1ea1302f7dd7075a4d41481489883eaff md5: 9373034735566df29779429f0c0de511 @@ -10110,20 +10097,23 @@ packages: - pkg:pypi/wrapt?source=hash-mapping size: 63385 timestamp: 1756851987645 -- pypi: ../eozilla/wraptile - name: wraptile - version: 0.0.8 - sha256: 436c794e970c9aebbbbe51a9454f8c7c395a8df52cebed220663569b8b682bf7 - requires_dist: +- conda: https://conda.anaconda.org/conda-forge/noarch/wraptile-0.0.8-pyhd8ed1ab_0.conda + sha256: 33aff6d7d98090448816b55088e6401534c6201127756b51ab33b61d6ba153fc + md5: 831533a291937737418394aae4835a6c + depends: - fastapi + - gavicore >=0.0.7 + - procodile >=0.0.7 - pydantic + - python >=3.10 - pyyaml - typer - uvicorn - - gavicore>=0.0.7 - - procodile>=0.0.7 - requires_python: '>=3.10' - editable: true + license: Apache-2.0 + purls: + - pkg:pypi/wraptile?source=hash-mapping + size: 26161 + timestamp: 1762857657232 - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.10.1-pyhcf101f3_1.conda sha256: 57bfac2a070d2c63d34c1d75a409cb92e788ac42e658e9d9349cd19b12888ce7 md5: 515d0ed77a942ad39fa94cf636dcde44 @@ -10159,72 +10149,72 @@ packages: - pkg:pypi/xarray?source=compressed-mapping size: 981473 timestamp: 1762776862272 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda - sha256: ed10c9283974d311855ae08a16dfd7e56241fac632aec3b92e3cfe73cff31038 - md5: f6ebe2cb3f82ba6c057dde5d9debe4f7 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda + sha256: 6bc6ab7a90a5d8ac94c7e300cc10beb0500eeba4b99822768ca2f2ef356f731b + md5: b2895afaf55bf96a8c8282a2e47a5de0 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 14780 - timestamp: 1734229004433 -- conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h6e16a3a_0.conda - sha256: b4d2225135aa44e551576c4f3cf999b3252da6ffe7b92f0ad45bb44b887976fc - md5: 4cf40e60b444d56512a64f39d12c20bd + size: 15321 + timestamp: 1762976464266 +- conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.conda + sha256: 928f28bd278c7da674b57d71b2e7f4ac4e7c7ce56b0bf0f60d6a074366a2e76d + md5: 47f1b8b4a76ebd0cd22bd7153e54a4dc depends: - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 13290 - timestamp: 1734229077182 -- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-h0e40799_0.conda - sha256: 047836241b2712aab1e29474a6f728647bff3ab57de2806b0bb0a6cf9a2d2634 - md5: 2ffbfae4548098297c033228256eb96e + size: 13810 + timestamp: 1762977180568 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda + sha256: 156a583fa43609507146de1c4926172286d92458c307bb90871579601f6bc568 + md5: 8436cab9a76015dfe7208d3c9f97c156 depends: - - libgcc >=13 + - libgcc >=14 - libwinpthread >=12.0.0.r4.gg4f2fc60ca - ucrt >=10.0.20348.0 license: MIT license_family: MIT purls: [] - size: 108013 - timestamp: 1734229474049 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda - sha256: 6b250f3e59db07c2514057944a3ea2044d6a8cdde8a47b6497c254520fade1ee - md5: 8035c64cb77ed555e3f150b7b3972480 + size: 109246 + timestamp: 1762977105140 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda + sha256: 25d255fb2eef929d21ff660a0c687d38a6d2ccfbcbf0cc6aa738b12af6e9d142 + md5: 1dafce8548e38671bea82e3f5c6ce22f depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 19901 - timestamp: 1727794976192 -- conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-libxdmcp-1.1.5-h00291cd_0.conda - sha256: bb4d1ef9cafef535494adf9296130b6193b3a44375883185b5167de03eb1ac7f - md5: 9f438e1b6f4e73fd9e6d78bfe7c36743 + size: 20591 + timestamp: 1762976546182 +- conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-libxdmcp-1.1.5-h8616949_1.conda + sha256: b7b291cc5fd4e1223058542fca46f462221027779920dd433d68b98e858a4afc + md5: 435446d9d7db8e094d2c989766cfb146 depends: - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 18465 - timestamp: 1727794980957 -- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-h0e40799_0.conda - sha256: 9075f98dcaa8e9957e4a3d9d30db05c7578a536950a31c200854c5c34e1edb2c - md5: 8393c0f7e7870b4eb45553326f81f0ff + size: 19067 + timestamp: 1762977101974 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda + sha256: 366b8ae202c3b48958f0b8784bbfdc37243d3ee1b1cd4b8e76c10abe41fa258b + md5: a7c03e38aa9c0e84d41881b9236eacfb depends: - - libgcc >=13 + - libgcc >=14 - libwinpthread >=12.0.0.r4.gg4f2fc60ca - ucrt >=10.0.20348.0 license: MIT license_family: MIT purls: [] - size: 69920 - timestamp: 1727795651979 + size: 70691 + timestamp: 1762977015220 - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.10.0-pyhd8ed1ab_0.conda sha256: c1b83ca08b11b5e8fa610e5e9721cf62bc67300fb951b7a189a0882565e2b391 md5: c98904dfa356df2e386db8af043be202 diff --git a/pyproject.toml b/pyproject.toml index 45de1a7..2d23c8d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,12 @@ channels = ["conda-forge"] platforms = ["linux-64", "win-64", "osx-64"] [tool.pixi.dependencies] +# Eozilla dependencies +appligator = ">=0.0.8,<0.0.9" +cuiman = ">=0.0.8,<0.0.9" +gavicore = ">=0.0.8,<0.0.9" +procodile = ">=0.0.8,<0.0.9" +wraptile = ">=0.0.8,<0.0.9" # Combined sub-workspace dependencies to prevent our editable # PyPI dependencies (our project's sub-workspaces) to install # PyPI packages instead of using conda packages. @@ -64,12 +70,15 @@ pymdown-extensions = "*" # See https://github.com/prefix-dev/pixi/issues/1417. s2gos-client = { path = "s2gos-client", editable = true } s2gos-server = { path = "s2gos-server", editable = true } -# TODO: once stable, move into project (conda-forge) dependencies -appligator = { path = "../eozilla/appligator", editable = true } -cuiman = { path = "../eozilla/cuiman", editable = true } -gavicore = { path = "../eozilla/gavicore", editable = true } -procodile = { path = "../eozilla/procodile", editable = true } -wraptile = { path = "../eozilla/wraptile", editable = true } +# +# Uncomment the following to allow using eozilla from sources +# Note, using the wraptile server is for testing only +# +#appligator = { path = "../eozilla/appligator", editable = true } +#cuiman = { path = "../eozilla/cuiman", editable = true } +#gavicore = { path = "../eozilla/gavicore", editable = true } +#procodile = { path = "../eozilla/procodile", editable = true } +#wraptile = { path = "../eozilla/wraptile", editable = true } # Airflow is only available on PyPI apache-airflow-client = "==3.0.2" From 9649d4c081b0a45be66770eaa0e39b74975ad0f7 Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Thu, 13 Nov 2025 14:12:26 +0100 Subject: [PATCH 14/16] Made `mkdocs serve` work again; removed mermaid as it is no longer required (it is in Eozilla) --- docs/architecture.md | 250 ---------------------------------------- docs/client-api.md | 18 ++- docs/process-dev.md | 269 ------------------------------------------- mkdocs.yml | 11 -- pixi.lock | 39 ------- pyproject.toml | 5 - 6 files changed, 8 insertions(+), 584 deletions(-) delete mode 100644 docs/architecture.md delete mode 100644 docs/process-dev.md diff --git a/docs/architecture.md b/docs/architecture.md deleted file mode 100644 index af508f3..0000000 --- a/docs/architecture.md +++ /dev/null @@ -1,250 +0,0 @@ -# Architecture - -_Note, should the following diagram code not render, copy it -into the [mermaid](https://www.mermaidchart.com/) editor._ - -## Overview - -```mermaid ---- -config: - class: - hideEmptyMembersBox: true - theme: default ---- -classDiagram -direction LR - namespace s2gos_client { - class api.AsyncClient - class api.Client - class gui.Client - class cli - } - namespace s2gos_common { - class models - class service.Service - } - namespace s2gos_server { - class server - class routes - class services.local.LocalService - class services.airflow.AirflowService - } - - cli ..> api.Client : use - gui.Client ..|> api.Client : inherits - api.Client ..> service.Service : uses - api.AsyncClient ..> service.Service : uses - service.Service ..> models : uses - services.local.LocalService --|> service.Service : implements - services.airflow.AirflowService --|> service.Service : implements - routes ..> service.Service : uses - server ..> routes : uses - server ..> services.local.LocalService : can run with - server ..> services.airflow.AirflowService : can run with - - note for gui.Client "will later inherit from AsyncClient" -``` - -## S2GOS Client - GUI - -Given here is the design used in package `s2gos_client.gui.component`. -The package contains the code to generate widgets and panels from the -JSON schema `s2gos_common.models.InputDescription` instances contained in -a `s2gos_common.models.ProcessDescription` instance. - -The `ComponentContainer` maps every `InputDescription` to a visual -`Component` that is created for a given JSON schema. - -```mermaid ---- -config: - class: - hideEmptyMembersBox: true - layout: elk ---- -classDiagram -direction LR - class models.InputDescription { - title - description - schema - } - class ComponentContainer { - \_\_init\_\_(input_descriptions) - get_components() - get_viewables() - } - ComponentContainer ..> ComponentFactoryRegistry : use - ComponentContainer o--> models.InputDescription : 1..n by name - ComponentContainer o--> Component : 1..n - ComponentFactory ..> Component : create - ComponentFactoryRegistry *--> ComponentFactory -``` - -A suitable `ComponentFactory` is selected for a given JSON schema -and will create the `Component` when it is needed. -The possible `ComponentFactory` instances are registered in a - `ComponentFactoryRegistry` singleton. - -```mermaid ---- -config: - class: - hideEmptyMembersBox: true - layout: dagre ---- -classDiagram -direction TB - class panel.viewable.Viewable { - \_\_panel\_\_() - } - class Component { - viewable - json_codec - _get_value_() - _set_value_(val) - _watch_value_(cb) - } - class WidgetComponent { - } - class ComponentFactory { - _accept_(schema) - _create_component_(schema) - } - class ComponentFactoryRegistry { - register_factory(factory, type, format) - find_factory(schema) - } - class ComponentFactoryBase { - type - format - accept(schema) - } - class BooleanCF { - } - class IntegerCF { - } - class NumberCF { - } - class StringCF { - } - class DateCF { - } - class BboxCF { - } - Component <|-- WidgetComponent - Component --> panel.viewable.Viewable : 1 - ComponentFactory ..> Component : create - ComponentFactoryRegistry *--> ComponentFactory : 0..N - ComponentFactory <|-- ComponentFactoryBase - ComponentFactoryBase <|-- BooleanCF - ComponentFactoryBase <|-- IntegerCF - ComponentFactoryBase <|-- NumberCF - ComponentFactoryBase <|-- StringCF - ComponentFactoryBase <|-- DateCF - ComponentFactoryBase <|-- BboxCF -``` - -## S2GOS Common - -Given here is the design used in package `s2gos_common.service`. - -```mermaid -classDiagram -direction TB - class Service { - get_conformance() - get_capabilities() - get_processes() - get_process(process_id) - execute_process(process_id, process_request) - get_jobs() - get_job(job_id) - get_job_result(job_id) - } - class ProcessList { - } - class ProcessSummary { - process_id - } - class ProcessDescription { - } - class ProcessRequest { - inputs - outputs - response - subscriber - } - class JobList { - } - class JobInfo { - process_id - job_id - status - progress - } - class JobResult { - } - class InputDescription { - schema - } - class Description { - title - description - } - ProcessList *--> ProcessSummary : 0 .. N - ProcessSummary --|> Description - ProcessDescription --|> ProcessSummary - ProcessDescription *--> InputDescription : 0 .. N by name - ProcessDescription *--> OutputDescription : 0 .. N by name - InputDescription --|> Description - OutputDescription --|> Description - JobList *--> JobInfo : 0 .. N - Service ..> ProcessList : obtain - Service ..> ProcessDescription : obtain - Service ..> JobList : obtain - Service ..> JobInfo : obtain - Service ..> JobResult : obtain - Service ..> ProcessRequest : use -``` - -## Code generation - -```mermaid ---- -config: - theme: default ---- -flowchart LR - openapi@{ shape: lean-r, label: "OpenAPI.yaml" } - sync_client@{ shape: stadium, label: "s2gos_client.api.Client" } - async_client@{ shape: stadium, label: "s2gos_client.api.AsyncClient" } - models@{ shape: stadium, label: "s2gos_common.models.*" } - service@{ shape: stadium, label: "s2gos_common.service.Service" } - routes@{ shape: stadium, label: "s2gos_server.routes" } - openapi --> generate - generate --> gen-client - generate --> gen-common - generate --> gen-server - gen-client --> sync_client - gen-client --> async_client - gen-common --> models - gen-common --> service - gen-server --> routes -``` - - -Generating Airflow DAGs: - -```mermaid ---- -config: - theme: default ---- -flowchart LR - local_service@{ shape: stadium, label: "s2gos_server.services.local.testing:service" } - dags@{ shape: stadium, label: "s2gos_airflow/dags" } - local_service --> gen-dags - gen-dags --> dags -``` diff --git a/docs/client-api.md b/docs/client-api.md index bd32483..4c3bcb0 100644 --- a/docs/client-api.md +++ b/docs/client-api.md @@ -1,17 +1,15 @@ # Client API Reference -The [`Client`](#s2gos_client.Client) class provides a synchronous API. +The entrypoint of the S2GOS client API is the `s2gos_client.Client` class that +provides a synchronous API for interacting with the S2GOS processing service. If you want an asynchronous version, use the `AsyncClient` class instead. It provides the same interface, but using asynchronous server calls. -Both clients return their configuration as a -[`ClientConfig`](#s2gos_client.ClientConfig) object. +Both clients return their configuration as a `s2gos_client.ClientConfig` object. -Methods of the [`Client`](#s2gos_client.Client) and `AsyncClient` -may raise a [`ClientError`](#s2gos_client.ClientError) if a server call fails. +Methods of the `s2gos_client.Client` and `s2gos_client.AsyncClient` +may raise a `s2gos_client.ClientError` if a server call fails. -::: s2gos_client.Client - -::: s2gos_client.ClientConfig - -::: s2gos_client.ClientError +The S2GOS client API is a thin wrapper around the +[Eozilla](https://eo-tools.github.io/eozilla/) Client API +called [Cuiman](https://eo-tools.github.io/eozilla/client-api/). diff --git a/docs/process-dev.md b/docs/process-dev.md deleted file mode 100644 index 8bcaaf0..0000000 --- a/docs/process-dev.md +++ /dev/null @@ -1,269 +0,0 @@ -# Process Development - -The package `s2gos_common` provides a simple **processor development framework** that - - - supports registration of processes from Python functions, - - supports progress reporting by subscriber callback URLs, and - - provides a command-line interface (CLI) to query and execute - the registered processes. - -Processor packages developed using the provided CLI can later on be used to -generate Docker images, Airflow DAGs, and optionally OGC Application Packages. - -You find the processor framework in the `s2gos_common.processes` package. -It comprises just a few handy top-level components: - -* [class `ProcessRegistry`][s2gos_common.process.ProcessRegistry] - to register your - Python functions as processes in a central collection. -* [class `JobContext`][s2gos_common.process.JobContext] - used inside your process - implementations to report progress or check for client-side cancellation. -* [function `get_cli()`][s2gos_common.process.get_cli] - generates a CLI for the - processes in the registry. - - -## Development Recipe - -Framework usage is simple, it is a 3-step process: - -1. Populate process registry with processes derived from your Python functions. -2. Define a CLI instance from that process registry. -3. Define an entry point script for the CLI instance, so you can run your package - as an application. - -The steps are explained in more detail in the following. - -### 1. Populate process registry - -First, you'll create a process registry object of type `ProcessRegistry`. -Use the registry's `process` decorator to register your Python functions -that should be exposed as processes. In `my_package/processes.py`: - -```python -from s2gos_common.process import JobContext, ProcessRegistry - -registry = ProcessRegistry() - - -@registry.process(id="my-process-1") -def my_process_1(path: str, threshold: float = 0.5) -> str: - ctx = JobContext.get() - ... - ctx.report_progress(progress=15, message="Initialized sources") - ... - - -@registry.process(id="my-process-2") -def my_process_2(ctx: JobContext, path: str, factor: float = 1.0) -> str: - ... -``` - -The `ctx` object of type [JobContext][s2gos_common.process.JobContext] -can be used to report progress and to check for job cancellation. -You can get the job context inside the function body via `JobContext.get()` -or declare it as a function argument of type `JobContext`. - -Process inputs, such as the arguments `path` or `factor` above, -can be further specified by -[`pydantic.Field`](https://docs.pydantic.dev/latest/concepts/fields/) annotations. -Field annotations for an argument can be provided via the `input_fields` dictionary -passed to the [`process`][s2gos_common.process.ProcessRegistry.process] decorator, -or preferably as part of the type declaration using the Python `Annotated` -special form. An example for the latter is -`factor: Annotated[float, Field(title="Scaling factor", gt=0., le=10.)] = 1.0`. - -Should your process have many arguments, you may consider defining them elsewhere -in a dedicated _pydantic Model_ derived from -[`pydantic.BaseModel`](https://docs.pydantic.dev/latest/concepts/models/), pass -it as single parameter to your function, and pass `inputs_arg=True` to the -`@process` decorator. Now the generated process description will report the class' -fields as inputs rather than the model class as single input. Conceptually: - -```python -from typing import Annotated - -from pydantic import BaseModel, Field -from s2gos_common.process import JobContext, ProcessRegistry - - -class ArgsModel(BaseModel): - # Required positional arguments - arg1: Annotated[Type1, Field(..., **Specs1] - arg2: Annotated[Type2, Field(..., **Specs2] - # ... - # Optional keyword arguments - kwarg1: Annotated[Type1, Field(..., Specs1] = Default1 - kwarg2: Annotated[Type2, Field(..., Specs2] = Default2 - # ... - - -registry = ProcessRegistry() - -@registry.process(inputs_arg=True) -def my_func(args: ArgsModel) -> MyResult: - ... -``` - -### 2. Define CLI instance - -In a second step you define an instance of a common process CLI and pass it -a reference to your registry instance. In `my_package/cli.py`: - -```python -from s2gos_common.process.cli.cli import get_cli - -# The CLI with a basic set of commands. -# The `cli` is a Typer application of type `typer.Typer()`, -# so can use the instance to register your own commands. -cli = get_cli("my_package.processes:registry") -``` - -You could also pass the imported registry directly, but using a -reference string defers importing the registry instance until it is -needed. This makes the CLI much faster if it is just called with -the `--help` option and hence no importing of yet unused libraries -takes place. - -### 3. Define entry point script - -In a last step you expose the CLI as an entry point script of your package. -In your `pyproject.toml`: - -```toml -[project.scripts] -my-tool = "my_package.cli:cli" -``` - -After installing `my_package` in a Python environment using `pip` or `pixi` -you can run your CLI as an executable and `my-tool --help` will output: - -![process-cli.png](assets/process-cli.png) - -## Usage Example - -### Example project setup - -An application example that can serve as a starting point is provided in the workspace -[s2gos-app-ex](https://github.com/s2gos-dev/s2gos-controller/tree/main/s2gos-app-ex). Please check out its `README.md` to install and run it. - -The application's primary user interface is its simple, generated CLI -(you can extend it, if you like). For the above application example the CLI tool -is named `s2gos-app-ex`. - -### Getting process information - -Use `list-processes` (or short `lp`) subcommand to list the published processes, and use -`get-process` (or short `gp`) to get the details like the inputs of your your process. -The command `s2gos-app-ex gp primes_between` will give you the input specs of the -published process `primes_between`: - -```json -{ - "title": "Prime Generator", - "description": "Computes the list of prime numbers within an integer value range.", - "id": "primes_between", - "version": "0.0.0", - "inputs": { - "min_val": { - "title": "Minimum value of search range", - "minOccurs": 0, - "schema": { - "minimum": 0.0, - "type": "integer", - "default": 0 - } - }, - "max_val": { - "title": "Maximum value of search range", - "minOccurs": 0, - "schema": { - "minimum": 0.0, - "type": "integer", - "default": 100 - } - } - }, - "outputs": { - "return_value": { - "title": "Return Value", - "schema": { - "type": "array", - "items": { - "type": "integer" - } - } - } - } -} -``` - -### Executing a process - -To execute your processes, see help for the `execute-process` (or short `ep`) -subcommand: - -![process-ep-cli.png](assets/process-ep-cli.png) - -### Execution request files - -For larger or complex sets of input parameters it is recommended to use a -_execution request file_ in JSON or YAML format. The structure is simple, for example: - -```json -{ - "process_id": "primes_between", - "inputs": { - "min_val": 100, - "max_val": 200 - } -} -``` - -The process request file format in detail: - -- `process_id`: Process identifier -- `dotpath`: Whether dots in input names should be used to create - nested object values. Defaults to `False`. -- `inputs`: Optional process inputs given as key-value mapping. - Values may be of any JSON-serializable type accepted by - the given process. -- `outputs`: Optional process outputs given as key-value mapping. - Values are of type [Output][s2gos_common.models.Output] - and should be supported by the given process. -- `subscriber`: Optional object comprising callback - URLs that are informed about process status changes - while the processing takes place. The URLs are `successUri`, - `inProgressUri`, and `failedUri` and none is required. - See also [Subscriber][s2gos_common.models.Subscriber]. - - -## Framework API - -::: s2gos_common.process.ProcessRegistry - options: - show_source: false - heading_level: 3 - -::: s2gos_common.process.Process - options: - show_source: false - heading_level: 3 - -::: s2gos_common.process.JobContext - options: - show_source: false - heading_level: 3 - -::: s2gos_common.process.JobCancelledException - options: - show_source: false - heading_level: 3 - -::: s2gos_common.process.get_cli - options: - show_source: false - heading_level: 3 - -::: s2gos_common.process.ExecutionRequest - options: - show_source: false - heading_level: 3 diff --git a/mkdocs.yml b/mkdocs.yml index ddec47d..24ad5cf 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -11,7 +11,6 @@ copyright: Copyright © 2025 ESA DTE-S2GOS Team nav: - Overview: index.md - Installation: installation.md - - Architecture: architecture.md - Client CLI: client-cli.md - Client API: client-api.md - Client Usage: @@ -19,7 +18,6 @@ nav: - notebooks/client-api.ipynb - notebooks/client-api-airflow.ipynb - notebooks/client-cli.ipynb - - Process Development: process-dev.md - Contributing: contributing.md - Roadmap: roadmap.md @@ -50,19 +48,11 @@ markdown_extensions: - attr_list - admonition - pymdownx.details - - pymdownx.superfences: - # make exceptions to highlighting of code: - custom_fences: - - name: mermaid - class: mermaid - format: !!python/name:mermaid2.fence_mermaid_custom - # - pymdownx.highlight - pymdownx.emoji: emoji_index: !!python/name:material.extensions.emoji.twemoji emoji_generator: !!python/name:material.extensions.emoji.to_svg extra: - mermaid: true social: - icon: fontawesome/brands/github link: https://github.com/s2gos-dev/s2gos-controller @@ -72,7 +62,6 @@ extra: plugins: - search - autorefs - - mermaid2 - mkdocs-jupyter - mkdocstrings: handlers: diff --git a/pixi.lock b/pixi.lock index dbb616c..d736b92 100644 --- a/pixi.lock +++ b/pixi.lock @@ -381,9 +381,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py313h54dd161_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda - pypi: https://files.pythonhosted.org/packages/53/c7/d168dd2e2120b1a61ffdcf6eaa6d992620a793d3bf7e12a59704eda1d83b/apache_airflow_client-3.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl - pypi: ./s2gos-client - pypi: ./s2gos-server osx-64: @@ -748,9 +745,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.25.0-py313hcb05632_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h8210216_2.conda - pypi: https://files.pythonhosted.org/packages/53/c7/d168dd2e2120b1a61ffdcf6eaa6d992620a793d3bf7e12a59704eda1d83b/apache_airflow_client-3.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl - pypi: ./s2gos-client - pypi: ./s2gos-server win-64: @@ -1106,9 +1100,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.25.0-py313h5fd188c_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-hbeecb71_2.conda - pypi: https://files.pythonhosted.org/packages/53/c7/d168dd2e2120b1a61ffdcf6eaa6d992620a793d3bf7e12a59704eda1d83b/apache_airflow_client-3.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl - pypi: ./s2gos-client - pypi: ./s2gos-server packages: @@ -2980,13 +2971,6 @@ packages: - pkg:pypi/editables?source=hash-mapping size: 10828 timestamp: 1733208220327 -- pypi: https://files.pythonhosted.org/packages/96/fd/a40c621ff207f3ce8e484aa0fc8ba4eb6e3ecf52e15b42ba764b457a9550/editorconfig-0.17.1-py3-none-any.whl - name: editorconfig - version: 0.17.1 - sha256: 1eda9c2c0db8c16dbd50111b710572a5e6de934e39772de1959d41f64fc17c82 - requires_dist: - - mypy>=1.15 ; extra == 'dev' - requires_python: '>=3.9' - conda: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.3.0-pyhd8ed1ab_0.conda sha256: c37320864c35ef996b0e02e289df6ee89582d6c8e233e18dc9983375803c46bb md5: 3bc0ac31178387e8ed34094d9481bfe8 @@ -3746,13 +3730,6 @@ packages: - pkg:pypi/jinja2?source=hash-mapping size: 112714 timestamp: 1741263433881 -- pypi: https://files.pythonhosted.org/packages/2d/14/1c65fccf8413d5f5c6e8425f84675169654395098000d8bddc4e9d3390e1/jsbeautifier-1.15.4-py3-none-any.whl - name: jsbeautifier - version: 1.15.4 - sha256: 72f65de312a3f10900d7685557f84cb61a9733c50dcc27271a39f5b0051bf528 - requires_dist: - - six>=1.13.0 - - editorconfig>=0.12.2 - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.12.1-pyhd8ed1ab_0.conda sha256: 4e08ccf9fa1103b617a4167a270768de736a36be795c6cd34c2761100d332f74 md5: 0fc93f473c31a2f85c0bde213e7c63ca @@ -6910,22 +6887,6 @@ packages: - pkg:pypi/mkdocs-material-extensions?source=hash-mapping size: 16122 timestamp: 1734641109286 -- pypi: https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl - name: mkdocs-mermaid2-plugin - version: 1.2.3 - sha256: 33f60c582be623ed53829a96e19284fc7f1b74a1dbae78d4d2e47fe00c3e190d - requires_dist: - - beautifulsoup4>=4.6.3 - - jsbeautifier - - mkdocs>=1.0.4 - - pymdown-extensions>=8.0 - - requests - - setuptools>=18.5 - - mkdocs-macros-test ; extra == 'test' - - mkdocs-material ; extra == 'test' - - packaging ; extra == 'test' - - requests-html ; extra == 'test' - requires_python: '>=3.8' - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.30.1-pyhd8ed1ab_0.conda sha256: bbbf409f50442f196debddcd0be5135c5fc6e25bd656185975383e0ee23b741d md5: 04b12b1aef52ba590a7ec9a78c77a51a diff --git a/pyproject.toml b/pyproject.toml index 2d23c8d..9ed1e9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,8 +61,6 @@ mkdocstrings = "*" mkdocstrings-python = "*" mkdocs-jupyter = "*" nbformat = "*" -# For mermaid diagrams -pymdown-extensions = "*" [tool.pixi.pypi-dependencies] # I wished we could have "no-deps=true" here, @@ -82,9 +80,6 @@ s2gos-server = { path = "s2gos-server", editable = true } # Airflow is only available on PyPI apache-airflow-client = "==3.0.2" -# Documentation -# For mermaid diagrams -mkdocs-mermaid2-plugin = "*" [tool.isort] skip = [".idea", ".github", ".pixi", "htmlcov", "site"] From 09b553f21067f8ea6fc67e1e02aaa6531f13756c Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Thu, 13 Nov 2025 14:24:09 +0100 Subject: [PATCH 15/16] Update --- README.md | 9 ++++++++- docs/index.md | 22 +++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 32910d2..c36ef1c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Python control layer for the synthetic EO scene simulator service of the _Note, this project and its documentation is still in an early development stage._ -## Description +## Controller Overview This project hosts two Python packages: @@ -27,6 +27,13 @@ This project hosts two Python packages: [OGC API - Processes](https://ogcapi.ogc.org/processes/) that is wrapped around the S2GOS scene simulator service based on [Apache Airflow](https://airflow.apache.org/). +The development of the S2GOS controller paved the way for the development of the more +general [Eozilla Suite](https://eo-tools.github.io/eozilla/) of tools supporting the +interaction with EO workflow orchestration and processing systems. The S2GOS controller +therefore build on the Eozilla packages +[Cuiman](https://github.com/eo-tools/eozilla/tree/main/cuiman), +[Wraptile](https://github.com/eo-tools/eozilla/tree/main/wraptile) and others. + ## Installation ### Using pip diff --git a/docs/index.md b/docs/index.md index 0d2d751..30d8ca8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,6 +4,8 @@ The Python control layer for the ESA DTE-S2GOS synthetic scene generator service ![logo.svg](assets/logo.svg){ .centered-logo width="300"} +## Project Overview + The _Digital Twin Earth Synthetic Scene Generator and Observation Simulator_ (DTE-S2GOS) project consists in the development of a new component of the [ESA Destination Earth Initiative](https://destination-earth.eu/) @@ -14,7 +16,25 @@ realistic synthetic 3D scenes of the Earth and simulate ground-based or spacebor remote sensing observations, among other with the [Eradiate Radiative Transfer Model](https://github.com/eradiate/eradiate). +[The Project](https://dte-s2gos.rayference.eu/about/){ .md-button .md-button--primary } + +## Controller Overview + **Note, this project and its documentation is still in an early development stage.** -[The Project](https://dte-s2gos.rayference.eu/about/){ .md-button .md-button--primary } +This project hosts two Python packages: + +* `s2gos-client` - CLI, GUI, and API clients that allow for interaction + with the S2GOS scene simulator service. +* `s2gos-server` - a FastAPI-based implementation of the + [OGC API - Processes](https://ogcapi.ogc.org/processes/) that is wrapped around + the S2GOS scene simulator service based on [Apache Airflow](https://airflow.apache.org/). + +The development of the S2GOS controller paved the way for the development of the more +general [Eozilla Suite](https://eo-tools.github.io/eozilla/) of tools supporting the +interaction with EO workflow orchestration and processing systems. The S2GOS controller +therefore build on the Eozilla packages +[Cuiman](https://github.com/eo-tools/eozilla/tree/main/cuiman), +[Wraptile](https://github.com/eo-tools/eozilla/tree/main/wraptile) and others. + [Get Started](installation){ .md-button .md-button--primary } From a68f190ac1ace9212a5792addd38fae292567a5c Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Thu, 13 Nov 2025 14:28:27 +0100 Subject: [PATCH 16/16] Update --- docs/index.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/index.md b/docs/index.md index 30d8ca8..4054bdb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,9 +1,12 @@ -# DTE-S2GOS Controller +# Overview The Python control layer for the ESA DTE-S2GOS synthetic scene generator service ![logo.svg](assets/logo.svg){ .centered-logo width="300"} +_Note, the S2GOS controller project and its documentation are still in an early +development stage._ + ## Project Overview The _Digital Twin Earth Synthetic Scene Generator and Observation Simulator_ @@ -20,8 +23,6 @@ remote sensing observations, among other with the ## Controller Overview -**Note, this project and its documentation is still in an early development stage.** - This project hosts two Python packages: * `s2gos-client` - CLI, GUI, and API clients that allow for interaction