diff --git a/CHANGES.md b/CHANGES.md index 8fffecf..754bd73 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,10 @@ +## Changes in version 0.0.6 (in development) + +- 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 - In `s2gos_client`: diff --git a/README.md b/README.md index 0ff9d9f..c36ef1c 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,195 @@ [![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._ + +## Controller Overview + +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. + +## 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/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/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 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/index.md b/docs/index.md index 7572c44..4054bdb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,13 +1,41 @@ -# 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"} -
-
-The Python control layer for the ESA DTE-S2GOS synthetic scene generator service. -**Note, this project and its documentation is still in an early development stage.** -
-
+_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_ +(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). [The Project](https://dte-s2gos.rayference.eu/about/){ .md-button .md-button--primary } -[Get Started](client-cli){ .md-button .md-button--primary } + +## Controller Overview + +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 } 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/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 4f1625a..24ad5cf 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,7 +10,7 @@ copyright: Copyright © 2025 ESA DTE-S2GOS Team nav: - Overview: index.md - - Architecture: architecture.md + - Installation: installation.md - Client CLI: client-cli.md - Client API: client-api.md - Client Usage: @@ -18,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 @@ -49,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 @@ -71,7 +62,6 @@ extra: plugins: - search - autorefs - - mermaid2 - mkdocs-jupyter - mkdocstrings: handlers: 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 d7f4fff..d736b92 100644 --- a/pixi.lock +++ b/pixi.lock @@ -9,1081 +9,1098 @@ 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/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-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_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_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 + - 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/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/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.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.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.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 + - 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/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 + - 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/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 - 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/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.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_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-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-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_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 - 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/sniffio-1.3.1-pyhd8ed1ab_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_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.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.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 - - 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-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 - 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.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_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 - 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/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/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/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-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 + - 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: ./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/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.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_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_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 + - 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/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/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.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.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.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.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 + - 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/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 + - 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/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 - 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/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.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_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-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.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 - - 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_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_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/sniffio-1.3.1-pyhd8ed1ab_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-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.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.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 - - 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-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 - 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.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-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 - 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/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/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/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-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 + - 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: ./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/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-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_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_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 - 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.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.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.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 + - 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/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 + - 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/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.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/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 + - 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_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-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-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_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_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/sniffio-1.3.1-pyhd8ed1ab_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_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.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.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 - - 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-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 - 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.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 + - 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_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 - 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/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/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-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 + - 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: ./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 @@ -1122,6 +1139,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 @@ -1134,25 +1173,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 + - 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 name: apache-airflow-client version: 3.0.2 @@ -1162,6 +1201,21 @@ packages: - python-dateutil - urllib3>=2.1.0 requires_python: ~=3.9 +- 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 + 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 @@ -1173,17 +1227,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 @@ -1196,67 +1250,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 + - 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 sha256: 93b14414b3b3ed91e286e1cbe4e7a60c4e1b1c730b0814d1e452a8ac4b9af593 md5: 8f587de4bcf981e26228f268df374a9b @@ -1283,751 +1338,744 @@ 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_8.conda + sha256: e91d2fc0fddf069b8d39c0ce03eca834673702f7e17eda8e7ffc4558b948053d + md5: 1baf55dfcc138d98d437309e9aba2635 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: 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.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: 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.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: 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 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_3.conda + sha256: 8d84039ea1d33021623916edfc23f063a5bcef90e8f63ae7389e1435deb83e53 + md5: 70e83d2429b7edb595355316927dfbea depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - 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: 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: 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.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: 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.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: 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: - - libgcc >=13 + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - 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: 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: 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.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: 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.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: 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 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 @@ -2037,7 +2085,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 @@ -2073,19 +2121,19 @@ 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/noarch/black-25.1.0-pyh866005b_0.conda sha256: c68f110cd491dc839a69e340930862e54c00fb02cede5f1831fcf8a253bd68d2 md5: b9b0c42e7316aa6043bdfd49883955b8 @@ -2102,6 +2150,23 @@ packages: - pkg:pypi/black?source=hash-mapping 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.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/black?source=hash-mapping + size: 401564 + timestamp: 1738616279268 - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda sha256: a05971bb80cca50ce9977aad3f7fc053e54ea7d5321523efc7b9a6e12901d3cd md5: f0b4c8e370446ef89797608d60a564b3 @@ -2126,9 +2191,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 @@ -2144,104 +2209,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 @@ -2275,24 +2340,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.11.12-h4c7d964_0.conda + sha256: 686a13bd2d4024fc99a22c1e0e68a7356af3ed3304a8d3ff6bb56249ad4e82f0 + md5: f98fb7db808b94bc1ec5b0e62f9f1069 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: 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: 151069 - timestamp: 1749990087500 + 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 @@ -2315,89 +2380,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.11.12-pyhd8ed1ab_0.conda + sha256: 083a2bdad892ccf02b352ecab38ee86c3e610ba9a4b11b073ea769d55a115d32 + md5: 96a02a5c1a65470a7e4eedb644c872fd 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 + - 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 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 @@ -2405,20 +2470,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 @@ -2430,171 +2495,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: @@ -2603,14 +2662,32 @@ packages: license_family: BSD purls: - pkg:pypi/cryptography?source=hash-mapping - size: 1664068 - timestamp: 1749539269244 -- conda: https://conda.anaconda.org/conda-forge/linux-64/cytoolz-1.0.1-py313h536fd9c_0.conda - sha256: 4ed6220a9db0c0fbef44b0b6c642e8f20e4d60a52628fc4d995f8c0db5ad942e - md5: e886bb6a3c24f8b9dd4fcd1d617a1f64 + size: 1718808 + timestamp: 1760605188769 +- 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 + 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 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 @@ -2618,11 +2695,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 @@ -2632,69 +2709,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 @@ -2710,8 +2787,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 @@ -2728,50 +2805,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 @@ -2780,7 +2861,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 @@ -2794,43 +2875,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 @@ -2838,35 +2919,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 @@ -2890,34 +2971,27 @@ 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.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 @@ -2926,64 +3000,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 @@ -2996,17 +3088,29 @@ 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 + - pkg:pypi/fsspec?source=compressed-mapping + size: 146592 + timestamp: 1761840236679 +- 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 + 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 @@ -3077,17 +3181,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 @@ -3100,19 +3204,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 @@ -3187,48 +3292,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 @@ -3280,27 +3382,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 + - 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 sha256: c18ab120a0613ada4391b15981d86ff777b5690ca461ea7e9e49531e8f374745 md5: 63ccfdc3a3ce25b027b8767eb722fca8 @@ -3342,98 +3434,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 @@ -3452,22 +3547,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 @@ -3475,24 +3568,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 @@ -3500,8 +3591,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 @@ -3514,22 +3605,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 @@ -3557,17 +3648,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 @@ -3592,9 +3684,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 @@ -3602,8 +3694,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 @@ -3635,111 +3727,104 @@ 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 - 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.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 @@ -3757,20 +3842,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 @@ -3807,36 +3892,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 @@ -3854,7 +3945,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 @@ -3868,9 +3959,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 @@ -3884,7 +3975,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 @@ -3896,8 +3987,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 @@ -3910,14 +4001,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 @@ -3925,7 +4016,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 @@ -3933,9 +4024,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 @@ -3950,43 +4041,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 + - 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 + 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 @@ -3999,8 +4089,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 @@ -4055,15 +4145,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 @@ -4106,6 +4197,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 @@ -4145,18 +4247,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 @@ -4192,514 +4294,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: 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 + - 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: 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: 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 >=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-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: 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 >=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 + - 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: 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: 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 >=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-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: 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 + 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 @@ -4732,97 +4893,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 @@ -4900,262 +5061,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: @@ -5163,308 +5324,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 @@ -5534,42 +5696,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 @@ -5580,33 +5742,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 @@ -5615,18 +5777,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 @@ -5635,195 +5797,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 @@ -5853,39 +6022,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 @@ -5925,229 +6094,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: @@ -6155,8 +6327,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 @@ -6199,49 +6371,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 - - icu >=75.1,<76.0a0 - 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: 609197 - timestamp: 1746634704204 -- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.8-h442d1da_0.conda - sha256: 473b8a53c8df714d676ab41711551c8d250f8d799f2db5cb7cb2b177a0ce13f6 - md5: 833c2dbc1a5020007b520b044c713ed3 + 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.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT + - 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: 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.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 @@ -6293,18 +6523,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: 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: 306443 - timestamp: 1749892271445 + size: 347688 + timestamp: 1762315988146 - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 sha256: 9afe0b5cfa418e8bdb30d8917c5a6cec10372b037924916f1f85b9f4899a67a6 md5: 91e27ef3d05cc772ce627e51cff111c4 @@ -6316,51 +6562,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 @@ -6396,36 +6648,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: @@ -6434,11 +6686,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 @@ -6449,49 +6701,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 @@ -6514,19 +6766,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 @@ -6554,20 +6806,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 @@ -6600,28 +6852,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 @@ -6635,25 +6887,9 @@ 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 - name: mkdocs-mermaid2-plugin - version: 1.2.1 - sha256: 22d2cf2c6867d4959a5e0903da2dde78d74581fc0b107b791bc4c7ceb9ce9741 - 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.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 @@ -6663,99 +6899,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 @@ -6766,11 +7005,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 @@ -6783,11 +7022,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 @@ -6796,14 +7035,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 @@ -6815,18 +7054,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 @@ -6842,20 +7080,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 @@ -6871,29 +7109,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 @@ -6939,38 +7177,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 @@ -6983,16 +7225,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 @@ -7001,17 +7243,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 @@ -7020,220 +7262,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 @@ -7255,7 +7501,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 @@ -7269,185 +7515,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 + - 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.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 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 - 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 @@ -7459,16 +7705,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 @@ -7480,11 +7727,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 @@ -7496,17 +7742,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 @@ -7531,19 +7778,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 @@ -7552,100 +7799,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 @@ -7668,28 +7907,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 - 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 +- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda + sha256: 7efd51b48d908de2d75cbb3c4a2e80dd9454e1c5bb8191b261af3136f7fa5888 + md5: 5c7a868f8241e64e1cf5fdf4962f23e2 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 @@ -7698,9 +7927,23 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/pluggy?source=compressed-mapping + - pkg:pypi/pluggy?source=hash-mapping size: 24246 timestamp: 1747339794916 +- 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 + 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 @@ -7730,84 +7973,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 @@ -7862,62 +8107,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 @@ -7928,14 +8174,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 @@ -7947,19 +8194,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 @@ -7967,8 +8215,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 @@ -7981,42 +8229,41 @@ 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_1.conda + sha256: b15568ddc03bd33ea41610e5df951be4e245cd61957cbf8c2cfd12557f3d53b5 + md5: f27c39a1906771bbe56cd26a76bf0b8b 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: - __glibc >=2.17 license: MIT - 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: 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 @@ -8025,30 +8272,28 @@ packages: constrains: - __osx >=10.13 license: MIT - 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 + - 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 - - 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 + - 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 @@ -8057,52 +8302,51 @@ 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.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: 171431 - timestamp: 1750571864207 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-core-11.1-py313h6971d95_0.conda - sha256: 17d1aeea68b091508e2bc8e58023788dcd7592143c909ede5b634d059d930f30 - md5: 6b77cb82a5311aa457295cec63adbbc8 + size: 169949 + timestamp: 1762988007623 +- 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 license: MIT 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 + - 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 + 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 @@ -8128,149 +8372,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 + 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 @@ -8301,20 +8559,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 @@ -8340,36 +8598,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 @@ -8381,14 +8642,14 @@ 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 @@ -8396,11 +8657,11 @@ packages: 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 + 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 @@ -8410,24 +8671,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 @@ -8440,86 +8701,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 @@ -8541,12 +8808,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 @@ -8554,11 +8821,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 @@ -8570,9 +8837,9 @@ packages: license: Apache-2.0 license_family: APACHE purls: - - pkg:pypi/requests?source=hash-mapping - size: 59407 - timestamp: 1749498221996 + - 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 sha256: 2e4372f600490a6e0b3bac60717278448e323cab1c0fecd5f43f7c56535a99c5 md5: 36de09a8d3e5d5e6f4ee63af49e59706 @@ -8596,26 +8863,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 @@ -8624,27 +8904,26 @@ 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_2.conda + sha256: a324240a742bd109fa97661916823e6c2d45b4c6f58957225c914a06cf863794 + md5: 60c24f26f922abfc661967b0ef609935 depends: - python - - libgcc >=13 - __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: 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: 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 @@ -8652,146 +8931,115 @@ packages: constrains: - __osx >=10.13 license: MIT - 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: 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.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: 238558 + timestamp: 1762984540101 +- 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: + - python - __osx >=10.13 - - libcxx >=18 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 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: bcf9b35cf8dde8c393c51de92d933cf68c3f7e57765e239c71fadf6e0da497fa - 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.5 - sha256: 4e77f36c91b27649db6e2dc0e765a33bfa9f1078ff34b4abffff4162a9332987 + version: 0.1.0.dev0 + sha256: 169c3f4b20de4b2267e655681771927382285c53a4b4cc92bea887965d0df1d3 requires_dist: - - click - - pydantic - - pyyaml - - typer - - uri-template - - httpx - - s2gos-common>=0.0.0 + - cuiman>=0.0.8 + - gavicore>=0.0.8 requires_python: '>=3.10' editable: true -- pypi: ./s2gos-common - name: s2gos-common - version: 0.0.5 - sha256: d55cf227264878aabce077c49c92034dc716f1b190427551c8c01832380dbfc7 - requires_dist: - - pydantic - - typer - requires_python: '>=3.10' - editable: true -- pypi: ./s2gos-server - name: s2gos-server - version: 0.0.5 - sha256: e76fcb0ac41e85054cac0e96f7ab520d6f5190c6cd238ff627bd1a4913f8026e - requires_dist: - - fastapi - - pydantic - - pyyaml - - typer - - uvicorn - - s2gos-common>=0.0.0 +- pypi: ./s2gos-server + name: s2gos-server + version: 0.1.0.dev0 + sha256: f4c7000a30dba249ffdc11683ec6b64b912eb0d59aa5225ff5e497a5532e431f + requires_dist: + - 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 @@ -8841,74 +9089,75 @@ 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_1.conda + sha256: 48f3f6a76c34b2cfe80de9ce7f2283ecb55d5ed47367ba91e8bb8104e12b8f11 + md5: 98b6c9dc80eb87b2519b97bcf7e578dd depends: + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 + - libstdcxx >=14 + - libgcc >=14 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: 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 - - 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: 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 + - 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 -- 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 @@ -8920,17 +9169,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 @@ -8945,44 +9194,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.2-pyhcf101f3_0.conda + sha256: 6b549360f687ee4d11bf85a6d6a276a30f9333df1857adb0fe785f0f8e9bcd60 + md5: f88bb644823094f436792f80fba3207e 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: 19397 + timestamp: 1762956379123 - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh0d859eb_0.conda sha256: b300557c0382478cf661ddb520263508e4b3b5871b471410450ef2846e8c352c md5: efba281bbdae5f6b0a1d53c6d4a97c93 @@ -9072,28 +9320,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 @@ -9113,37 +9351,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 @@ -9152,23 +9390,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 @@ -9191,29 +9429,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 @@ -9230,93 +9468,80 @@ 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-pyhefaf540_1.conda + sha256: 17a1e572939af33d709248170871d4da74f7e32b48f2e9b5abca613e201c6e64 + md5: 23a53fdefc45ba3f4e075cc0997fd13b depends: - - typer-slim-standard ==0.16.0 hf964461_0 - - python >=3.9 + - typer-slim-standard ==0.20.0 h4daf872_1 + - 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 + 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.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 + 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.16.0 pyhe01879c_0 + - typer-slim ==0.20.0 pyhcf101f3_1 - 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: 5322 + timestamp: 1762984042927 +- 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 @@ -9346,15 +9571,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 @@ -9393,35 +9619,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.9-h76e24b7_0.conda + sha256: 2e20f8c6e69374688cf8177a280b199c9c92161bf22465071f81832a3074f003 + md5: bc71e01e6f7abacff84011d596cb58d3 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: 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 >=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: 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 @@ -9431,194 +9657,205 @@ 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: 17495993 + timestamp: 1762996907985 +- 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_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: 142789 - timestamp: 1730492986088 -- conda: https://conda.anaconda.org/conda-forge/osx-64/watchdog-6.0.0-py313h63b0ddb_0.conda - sha256: ab2bf709f3cfd270a5d8491188e05fa68d92b9f84a30269e4db391093cbb9049 - md5: d83c209755e41be09f8107fbc884fa91 + - 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: 151270 - timestamp: 1730493213458 -- conda: https://conda.anaconda.org/conda-forge/win-64/watchdog-6.0.0-py313hfa70ccb_0.conda - sha256: 213d520704e528b2273b2701f0961048c5bdbefbe4db5cdabcf9d01d4322fbf8 - md5: 9593f7b5c1aa4be66a9945c4f1e9f043 + 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: 167930 - timestamp: 1730493160417 -- conda: https://conda.anaconda.org/conda-forge/linux-64/watchfiles-1.1.0-py313h920b4c0_0.conda - sha256: 5a27ec51a5de9a251ce7078739d0fc9301510992405fae5a29784c5daac3caeb - md5: c9f7604d02c82ec812444d5ccee625bd + size: 169318 + timestamp: 1763021892678 +- 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: @@ -9627,11 +9864,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 @@ -9643,46 +9880,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 @@ -9694,70 +9931,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 @@ -9776,23 +10016,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 @@ -9801,224 +10041,254 @@ 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 -- conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2025.6.1-pyhd8ed1ab_1.conda - sha256: e27b45ca791cfbcad37d64b8615d0672d94aafa00b014826fcbca2ce18bd1cc0 - md5: 145c6f2ac90174d9ad1a2a51b9d7c1dd + size: 63385 + timestamp: 1756851987645 +- conda: https://conda.anaconda.org/conda-forge/noarch/wraptile-0.0.8-pyhd8ed1ab_0.conda + sha256: 33aff6d7d98090448816b55088e6401534c6201127756b51ab33b61d6ba153fc + md5: 831533a291937737418394aae4835a6c depends: - - numpy >=1.24 - - packaging >=23.2 - - pandas >=2.1 + - fastapi + - gavicore >=0.0.7 + - procodile >=0.0.7 + - pydantic - python >=3.10 + - pyyaml + - typer + - uvicorn + 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 + depends: + - 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 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda - sha256: ed10c9283974d311855ae08a16dfd7e56241fac632aec3b92e3cfe73cff31038 - md5: f6ebe2cb3f82ba6c057dde5d9debe4f7 + - pkg:pypi/xarray?source=compressed-mapping + size: 981473 + timestamp: 1762776862272 +- 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 -- conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.4.0-pyhd8ed1ab_0.conda - sha256: ac6d4d4133b1e0f69075158cdf00fccad20e29fc6cc45faa480cec37a84af6ae - md5: 5663fa346821cd06dc1ece2c2600be2c + size: 70691 + timestamp: 1762977015220 +- 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 @@ -10064,51 +10334,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 diff --git a/pyproject.toml b/pyproject.toml index 066e972..9ed1e9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "s2gos-controller" -version = "0.0.5" -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] @@ -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. @@ -55,28 +61,31 @@ mkdocstrings = "*" mkdocstrings-python = "*" mkdocs-jupyter = "*" nbformat = "*" -# For mermaid diagrams -pymdown-extensions = "*" [tool.pixi.pypi-dependencies] # I wished we could have "no-deps=true" here, # 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 } +# +# 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" -# Documentation -# For mermaid diagrams -mkdocs-mermaid2-plugin = "*" [tool.isort] 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 @@ -84,10 +93,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", ] @@ -98,51 +105,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", + "s2gos-client/tests", + "s2gos-server/tests", "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" @@ -150,52 +145,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 5ba5134..0000000 --- a/s2gos-app-ex/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -# 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 -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-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/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 4c2bc50..0000000 --- a/s2gos-app-ex/pixi.lock +++ /dev/null @@ -1,1195 +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: ../s2gos-common - - 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: ../s2gos-common - - 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: ../s2gos-common - - 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: ../s2gos-common - - 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 -- 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 -- 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 -- 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: bcf9b35cf8dde8c393c51de92d933cf68c3f7e57765e239c71fadf6e0da497fa - requires_python: '>=3.10' - editable: true -- pypi: ../s2gos-common - name: s2gos-common - version: 0.0.4.dev0 - sha256: 18e640e32d505210d7bb0fbdf5695ca668a41489aa84cc5f41aa4fe658247c77 - requires_dist: - - pydantic - - typer - 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 b24081f..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] -s2gos-common = { path = "../s2gos-common", editable = true } -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 32afdf1..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 s2gos_common.process 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 974d434..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 s2gos_common.process 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 2fe8fa6..6998927 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.1.0.dev0" description = "Python client for the ESA DTE-S2GOS synthetic scene generator service" readme = "README.md" authors = [ @@ -38,14 +38,9 @@ classifiers = [ ] requires-python = ">=3.10" dependencies = [ - "click", - "pydantic", - "pyyaml", - "typer", - "uri-template", - "httpx", - # local dependency - "s2gos-common>=0.0.0", + # Eozilla dependencies + "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 ea2d812..38b3c01 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.async_client import AsyncClient -from .api.client import Client -from .api.config import ClientConfig -from .api.exceptions import ClientError +from .api import AsyncClient, Client, ClientConfig, ClientError __version__ = version("s2gos-client") @@ -18,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/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..b06fd69 100644 --- a/s2gos-client/src/s2gos_client/api/__init__.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 .async_client import AsyncClient -from .client import Client -from .config import ClientConfig -from .exceptions import ClientError +from cuiman.api import AsyncClient, Client, ClientConfig, 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/__init__.py b/s2gos-client/src/s2gos_client/api/transport/__init__.py deleted file mode 100644 index 0982b90..0000000 --- a/s2gos-client/src/s2gos_client/api/transport/__init__.py +++ /dev/null @@ -1,8 +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 .args import TransportArgs -from .transport import AsyncTransport, Transport, TransportError - -__all__ = ["AsyncTransport", "Transport", "TransportArgs", "TransportError"] 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/cli.py b/s2gos-client/src/s2gos_client/cli.py new file mode 100644 index 0000000..003fc4e --- /dev/null +++ b/s2gos-client/src/s2gos_client/cli.py @@ -0,0 +1,20 @@ +# 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 cuiman.cli import new_cli + +from s2gos_client import __version__ as version + +cli = new_cli( + name="s2gos-client", + version=version, + summary="Interact with the ESA DTE S2GOS processing service.", +) + +__all__ = [ + "cli", +] + +if __name__ == "__main__": # pragma: no cover + 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-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/s2gos_client/gui/__init__.py b/s2gos-client/tests/test_api.py similarity index 54% rename from s2gos-client/src/s2gos_client/gui/__init__.py rename to s2gos-client/tests/test_api.py index 779cce7..ede2fc8 100644 --- a/s2gos-client/src/s2gos_client/gui/__init__.py +++ b/s2gos-client/tests/test_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. -import panel as pn +import s2gos_client.api -from .client import Client -__all__ = ["Client"] - -pn.extension("ipywidgets", "tabulator", notifications=True) +def test_api_ok(): + assert {"AsyncClient", "Client", "ClientConfig", "ClientError"}.issubset( + dir(s2gos_client.api) + ) diff --git a/s2gos-common/src/s2gos_common/util/__init__.py b/s2gos-client/tests/test_cli.py similarity index 65% rename from s2gos-common/src/s2gos_common/util/__init__.py rename to s2gos-client/tests/test_cli.py index 22d05e1..eb050c8 100644 --- a/s2gos-common/src/s2gos_common/util/__init__.py +++ b/s2gos-client/tests/test_cli.py @@ -1,3 +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-common/src/tests/process/__init__.py b/s2gos-client/tests/test_gui.py similarity index 64% rename from s2gos-common/src/tests/process/__init__.py rename to s2gos-client/tests/test_gui.py index 22d05e1..e551555 100644 --- a/s2gos-common/src/tests/process/__init__.py +++ b/s2gos-client/tests/test_gui.py @@ -1,3 +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)) 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 5661a38..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.5" -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/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/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 475aa03..e6fae2c 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.1.0.dev0" description = "Python server for the ESA DTE-S2GOS synthetic scene generator service" readme = "README.md" authors = [ @@ -38,13 +38,9 @@ classifiers = [ ] requires-python = ">=3.10" dependencies = [ - "fastapi", - "pydantic", - "pyyaml", - "typer", - "uvicorn", - # local dependency - "s2gos-common>=0.0.0", + # Eozilla dependencies + "gavicore >=0.0.8", + "wraptile >=0.0.8", ] [project.scripts] @@ -74,4 +70,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/cli.py b/s2gos-server/src/s2gos_server/cli.py index a1d75a8..aff0662 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 new_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 = new_cli(name="s2gos-server", version=version) +__all__ = ["cli"] if __name__ == "__main__": # pragma: no cover cli() 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/__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-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_cli.py b/s2gos-server/src/tests/test_cli.py deleted file mode 100644 index 05cb361..0000000 --- a/s2gos-server/src/tests/test_cli.py +++ /dev/null @@ -1,82 +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 unittest.mock import MagicMock, patch - -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 - ) 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() 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-common/src/tests/__init__.py b/s2gos-server/tests/test_cli.py similarity index 65% rename from s2gos-common/src/tests/__init__.py rename to s2gos-server/tests/test_cli.py index 22d05e1..e0ed2c1 100644 --- a/s2gos-common/src/tests/__init__.py +++ b/s2gos-server/tests/test_cli.py @@ -1,3 +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_server.cli + + +def test_cli_ok(): + 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():