From ebed2a658dc9743d44d1601dcdbbeac762072eba Mon Sep 17 00:00:00 2001 From: Future-Outlier Date: Sat, 2 Dec 2023 07:46:31 +0800 Subject: [PATCH 01/19] add template (#4512) Signed-off-by: Future Outlier Co-authored-by: Future Outlier Co-authored-by: Kevin Su --- .github/PULL_REQUEST_TEMPLATE.md | 52 ++++++++++++++++---------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 13d4ff7668..166568ed6d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,10 +1,5 @@ - - ## Tracking issue +_https://github.com/flyteorg/flyte/issues/_ @@ -12,40 +7,45 @@ Happy contributing! -## Docs link +## Why are the changes needed? - + -## Describe your changes +## What changes were proposed in this pull request? - + + +## How was this patch tested? - +### Setup process + +### Screenshots + ## Check all the applicable boxes - [ ] I updated the documentation accordingly. - [ ] All new and existing tests passed. - [ ] All commits are signed-off. -## Setup Process - - - -## Screenshots - - - -## Note to reviewers - - - ## Related PRs +## Docs link + + From 1d334d2b10ad017b9e8f78d96427eeef7637210b Mon Sep 17 00:00:00 2001 From: Future-Outlier Date: Sat, 2 Dec 2023 20:05:27 +0800 Subject: [PATCH 02/19] [Docs] Databricks Agent Doc (#4008) Signed-off-by: Future Outlier Signed-off-by: Future-Outlier Signed-off-by: Kevin Su Co-authored-by: Future Outlier Co-authored-by: Kevin Su Co-authored-by: Kevin Su --- rsts/deployment/agents/bigquery.rst | 2 + rsts/deployment/agents/databricks.rst | 294 +++++++++++++++++++ rsts/deployment/agents/index.rst | 10 + rsts/deployment/agents/mmcloud.rst | 8 +- rsts/deployment/agents/sensor.rst | 2 + rsts/deployment/plugins/webapi/snowflake.rst | 4 +- 6 files changed, 316 insertions(+), 4 deletions(-) create mode 100644 rsts/deployment/agents/databricks.rst diff --git a/rsts/deployment/agents/bigquery.rst b/rsts/deployment/agents/bigquery.rst index ac6ec896bb..31d4ac6a67 100644 --- a/rsts/deployment/agents/bigquery.rst +++ b/rsts/deployment/agents/bigquery.rst @@ -102,3 +102,5 @@ Upgrade the Flyte Helm release Replace ```` with the name of your release (e.g., ``flyte``) and ```` with the name of your namespace (e.g., ``flyte``). + +For bigquery plugin on the Flyte cluster, please refer to `Bigquery Plugin Example `_ diff --git a/rsts/deployment/agents/databricks.rst b/rsts/deployment/agents/databricks.rst new file mode 100644 index 0000000000..7d5e2bb3e6 --- /dev/null +++ b/rsts/deployment/agents/databricks.rst @@ -0,0 +1,294 @@ +.. _deployment-agent-setup-databricks: + +Databricks Agent +================= + +This guide provides an overview of how to set up Databricks agent in your Flyte deployment. + +Spin up a cluster +----------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + You can spin up a demo cluster using the following command: + + .. code-block:: bash + + flytectl demo start + + Or install Flyte using the :ref:`flyte-binary helm chart `. + + .. group-tab:: Flyte core + + If you've installed Flyte using the + `flyte-core helm chart `__, please ensure: + + * You have the correct kubeconfig and have selected the correct Kubernetes context. + * You have configured the correct flytectl settings in ``~/.flyte/config.yaml``. + +.. note:: + + Add the Flyte chart repo to Helm if you're installing via the Helm charts. + + .. code-block:: bash + + helm repo add flyteorg https://flyteorg.github.io/flyte + +Databricks workspace +-------------------- + +To set up your Databricks account, follow these steps: + +1. Create a `Databricks account `__. + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/deployment/plugins/databricks/databricks_workspace.png + :alt: A screenshot of Databricks workspace creation. + +2. Ensure that you have a Databricks workspace up and running. + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/deployment/plugins/databricks/open_workspace.png + :alt: A screenshot of Databricks workspace. + +3. Generate a `personal access token + `__ to be used in the Flyte configuration. + You can find the personal access token in the user settings within the workspace. ``User settings`` -> ``Developer`` -> ``Access tokens`` + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/deployment/plugins/databricks/databricks_access_token.png + :alt: A screenshot of access token. + +4. Enable custom containers on your Databricks cluster before you trigger the workflow. + +.. code-block:: bash + + curl -X PATCH -n -H "Authorization: Bearer " \ + https:///api/2.0/workspace-conf \ + -d '{"enableDcs": "true"}' + +For more detail, check `custom containers `__. + +5. Create an `instance profile +`__ +for the Spark cluster. This profile enables the Spark job to access your data in the S3 bucket. + +Create an instance profile using the AWS console (For AWS Users) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. In the AWS console, go to the IAM service. +2. Click the Roles tab in the sidebar. +3. Click Create role. + + a. Under Trusted entity type, select AWS service. + b. Under Use case, select **EC2**. + c. Click Next. + d. At the bottom of the page, click Next. + e. In the Role name field, type a role name. + f. Click Create role. + +4. In the role list, click the **AmazonS3FullAccess** role. +5. Click Create role button. + +In the role summary, copy the Role ARN. + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/deployment/plugins/databricks/s3_arn.png + :alt: A screenshot of s3 arn. + +Locate the IAM role that created the Databricks deployment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +If you don’t know which IAM role created the Databricks deployment, do the following: + +1. As an account admin, log in to the account console. +2. Go to ``Workspaces`` and click your workspace name. +3. In the Credentials box, note the role name at the end of the Role ARN + +For example, in the Role ARN ``arn:aws:iam::123456789123:role/finance-prod``, the role name is finance-prod + +Edit the IAM role that created the Databricks deployment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1. In the AWS console, go to the IAM service. +2. Click the Roles tab in the sidebar. +3. Click the role that created the Databricks deployment. +4. On the Permissions tab, click the policy. +5. Click Edit Policy. +6. Append the following block to the end of the Statement array. Ensure that you don’t overwrite any of the existing policy. Replace with the role you created in Configure S3 access with instance profiles. + +.. code-block:: bash + + { + "Effect": "Allow", + "Action": "iam:PassRole", + "Resource": "arn:aws:iam:::role/" + } + +Specify agent configuration +---------------------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + .. tabs:: + + .. group-tab:: Demo cluster + + Enable the Databricks agent on the demo cluster by updating the ConfigMap: + + .. code-block:: bash + + kubectl edit configmap flyte-sandbox-config -n flyte + + .. code-block:: yaml + :emphasize-lines: 7,12,16 + + tasks: + task-plugins: + default-for-task-types: + container: container + container_array: k8s-array + sidecar: sidecar + spark: agent-service + enabled-plugins: + - container + - sidecar + - k8s-array + - agent-service + plugins: + agent-service: + supportedTaskTypes: + - spark + + .. group-tab:: Helm chart + + Edit the relevant YAML file to specify the plugin. + + .. code-block:: yaml + :emphasize-lines: 7,11,15 + + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - agent-service + default-for-task-types: + - container: container + - container_array: k8s-array + - spark: agent-service + plugins: + agent-service: + supportedTaskTypes: + - spark + + .. group-tab:: Flyte core + + Create a file named ``values-override.yaml`` and add the following config to it: + + .. code-block:: yaml + :emphasize-lines: 9,14-17 + + enabled_plugins: + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - agent-service + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + spark: agent-service + plugins: + agent-service: + supportedTaskTypes: + - spark + +Add the Databricks access token +------------------------------- + +You have to set the Databricks token to the Flyte configuration. + +1. Install flyteagent pod using helm + +.. code-block:: + + helm repo add flyteorg https://flyteorg.github.io/flyte + helm install flyteagent flyteorg/flyteagent --namespace flyte + +2. Get the base64 value of your Databricks token. + +.. code-block:: + + echo -n "" | base64 + +3. Edit the flyteagent secret + + .. code-block:: bash + + kubectl edit secret flyteagent -n flyte + + .. code-block:: yaml + :emphasize-lines: 3 + + apiVersion: v1 + data: + flyte_databricks_access_token: + kind: Secret + metadata: + annotations: + meta.helm.sh/release-name: flyteagent + meta.helm.sh/release-namespace: flyte + creationTimestamp: "2023-10-04T04:09:03Z" + labels: + app.kubernetes.io/managed-by: Helm + name: flyteagent + namespace: flyte + resourceVersion: "753" + uid: 5ac1e1b6-2a4c-4e26-9001-d4ba72c39e54 + type: Opaque + + +Upgrade the deployment +---------------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + .. tabs:: + + .. group-tab:: Demo cluster + + .. code-block:: + + kubectl rollout restart deployment flyte-sandbox -n flyte + + .. group-tab:: Helm chart + + .. code-block:: + + helm upgrade flyteorg/flyte-binary -n --values + + Replace ```` with the name of your release (e.g., ``flyte-backend``), + ```` with the name of your namespace (e.g., ``flyte``), + and ```` with the name of your YAML file. + + .. group-tab:: Flyte core + + .. code-block:: + + helm upgrade flyte/flyte-core -n --values values-override.yaml + + Replace ```` with the name of your release (e.g., ``flyte``) + and ```` with the name of your namespace (e.g., ``flyte``). + +Wait for the upgrade to complete. You can check the status of the deployment pods by running the following command: + +.. code-block:: + + kubectl get pods -n flyte + +For databricks plugin on the Flyte cluster, please refer to `Databricks Plugin Example `_ diff --git a/rsts/deployment/agents/index.rst b/rsts/deployment/agents/index.rst index af0bddaefd..4bc56f55c5 100644 --- a/rsts/deployment/agents/index.rst +++ b/rsts/deployment/agents/index.rst @@ -37,6 +37,15 @@ Discover the process of setting up Agents for Flyte. Guide to setting up the Sensor agent. + --- + + .. link-button:: deployment-agent-setup-databricks + :type: ref + :text: Databricks Agent + :classes: btn-block stretched-link + ^^^^^^^^^^^^ + Guide to setting up the Databricks agent. + .. toctree:: :maxdepth: 1 :name: Agent setup @@ -44,4 +53,5 @@ Discover the process of setting up Agents for Flyte. bigquery mmcloud + databricks sensor diff --git a/rsts/deployment/agents/mmcloud.rst b/rsts/deployment/agents/mmcloud.rst index 1e36ff7cfc..e2c2af9813 100644 --- a/rsts/deployment/agents/mmcloud.rst +++ b/rsts/deployment/agents/mmcloud.rst @@ -57,15 +57,15 @@ Enable the MMCloud agent by adding the following config to the relevant YAML fil .. code-block:: yaml tasks: - task-agents: - enabled-agents: + task-plugins: + enabled-plugins: - agent-service default-for-task-types: - mmcloud_task: agent-service .. code-block:: yaml - agents: + plugins: agent-service: agents: mmcloud-agent: @@ -117,3 +117,5 @@ Wait for the upgrade to complete. You can check the status of the deployment pod .. code-block:: kubectl get pods -n flyte + +For mmcloud plugin on the Flyte cluster, please refer to `Memory Machine Cloud Plugin Example `_ diff --git a/rsts/deployment/agents/sensor.rst b/rsts/deployment/agents/sensor.rst index ecb45e426f..fa886ca608 100644 --- a/rsts/deployment/agents/sensor.rst +++ b/rsts/deployment/agents/sensor.rst @@ -145,3 +145,5 @@ You can check the status of the deployment pods by running the following command .. code-block:: kubectl get pods -n flyte + +For sensor plugin on the Flyte cluster, please refer to `Sensor Plugin Example `_ diff --git a/rsts/deployment/plugins/webapi/snowflake.rst b/rsts/deployment/plugins/webapi/snowflake.rst index 85f13fe115..ac1faaa9dc 100644 --- a/rsts/deployment/plugins/webapi/snowflake.rst +++ b/rsts/deployment/plugins/webapi/snowflake.rst @@ -240,4 +240,6 @@ Wait for the upgrade to complete. You can check the status of the deployment pod .. code-block:: - kubectl get pods -n flyte \ No newline at end of file + kubectl get pods -n flyte + +For snowflake plugin on the Flyte cluster, please refer to `Snowflake Plugin Example `_ From 9df8677729c804d2a9471c20da74b6e50af5cb8e Mon Sep 17 00:00:00 2001 From: Eduardo Apolinario <653394+eapolinario@users.noreply.github.com> Date: Sat, 2 Dec 2023 11:10:17 -0800 Subject: [PATCH 03/19] Bump version of goreleaser gh action to v5 (#4519) --- .github/workflows/create_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 23e747318f..ff191b346c 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -177,7 +177,7 @@ jobs: git stash - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v2 + uses: goreleaser/goreleaser-action@v5 with: version: latest args: release --rm-dist --release-notes=CHANGELOG/CHANGELOG-${{ github.event.inputs.version }}.md From ad0597cd2b9854b23c24e77260e045038532281f Mon Sep 17 00:00:00 2001 From: Future-Outlier Date: Tue, 5 Dec 2023 00:18:57 +0800 Subject: [PATCH 04/19] Kf operators use `GetReplicaFunc` (Error Handling) (#4471) * fix bug Signed-off-by: Future Outlier * rename Signed-off-by: Future Outlier * rename Signed-off-by: Future Outlier * add test Signed-off-by: Future Outlier * move GetReplicaCount to common package Signed-off-by: Future Outlier * merge Signed-off-by: Future Outlier * merge Signed-off-by: Future Outlier --------- Signed-off-by: Future Outlier Co-authored-by: Future Outlier Co-authored-by: Kevin Su --- .../k8s/kfoperators/common/common_operator.go | 8 +++++++ .../tasks/plugins/k8s/kfoperators/mpi/mpi.go | 4 ++-- .../plugins/k8s/kfoperators/mpi/mpi_test.go | 14 +++++++++++++ .../k8s/kfoperators/pytorch/pytorch.go | 7 +++++-- .../k8s/kfoperators/pytorch/pytorch_test.go | 13 ++++++++++++ .../k8s/kfoperators/tensorflow/tensorflow.go | 21 +++++++------------ .../kfoperators/tensorflow/tensorflow_test.go | 8 +++---- 7 files changed, 54 insertions(+), 21 deletions(-) diff --git a/flyteplugins/go/tasks/plugins/k8s/kfoperators/common/common_operator.go b/flyteplugins/go/tasks/plugins/k8s/kfoperators/common/common_operator.go index 74021df2be..7e4b32e25e 100644 --- a/flyteplugins/go/tasks/plugins/k8s/kfoperators/common/common_operator.go +++ b/flyteplugins/go/tasks/plugins/k8s/kfoperators/common/common_operator.go @@ -345,3 +345,11 @@ func ToReplicaSpecWithOverrides(ctx context.Context, taskCtx pluginsCore.TaskExe return replicaSpec, nil } + +func GetReplicaCount(specs map[commonOp.ReplicaType]*commonOp.ReplicaSpec, replicaType commonOp.ReplicaType) *int32 { + if spec, ok := specs[replicaType]; ok && spec.Replicas != nil { + return spec.Replicas + } + + return new(int32) // return 0 as default value +} diff --git a/flyteplugins/go/tasks/plugins/k8s/kfoperators/mpi/mpi.go b/flyteplugins/go/tasks/plugins/k8s/kfoperators/mpi/mpi.go index 826e83b671..97199025a7 100644 --- a/flyteplugins/go/tasks/plugins/k8s/kfoperators/mpi/mpi.go +++ b/flyteplugins/go/tasks/plugins/k8s/kfoperators/mpi/mpi.go @@ -162,8 +162,8 @@ func (mpiOperatorResourceHandler) GetTaskPhase(_ context.Context, pluginContext return pluginsCore.PhaseInfoUndefined, fmt.Errorf("failed to convert resource data type") } - numWorkers = app.Spec.MPIReplicaSpecs[kubeflowv1.MPIJobReplicaTypeWorker].Replicas - numLauncherReplicas = app.Spec.MPIReplicaSpecs[kubeflowv1.MPIJobReplicaTypeLauncher].Replicas + numWorkers = common.GetReplicaCount(app.Spec.MPIReplicaSpecs, kubeflowv1.MPIJobReplicaTypeWorker) + numLauncherReplicas = common.GetReplicaCount(app.Spec.MPIReplicaSpecs, kubeflowv1.MPIJobReplicaTypeLauncher) taskLogs, err := common.GetLogs(pluginContext, common.MPITaskType, app.ObjectMeta, false, *numWorkers, *numLauncherReplicas, 0, 0) diff --git a/flyteplugins/go/tasks/plugins/k8s/kfoperators/mpi/mpi_test.go b/flyteplugins/go/tasks/plugins/k8s/kfoperators/mpi/mpi_test.go index 1cb6e9d826..d009c7c887 100644 --- a/flyteplugins/go/tasks/plugins/k8s/kfoperators/mpi/mpi_test.go +++ b/flyteplugins/go/tasks/plugins/k8s/kfoperators/mpi/mpi_test.go @@ -776,3 +776,17 @@ func TestBuildResourceMPIV1ResourceTolerations(t *testing.T) { assert.NotContains(t, mpiJob.Spec.MPIReplicaSpecs[kubeflowv1.MPIJobReplicaTypeLauncher].Template.Spec.Tolerations, gpuToleration) assert.Contains(t, mpiJob.Spec.MPIReplicaSpecs[kubeflowv1.MPIJobReplicaTypeWorker].Template.Spec.Tolerations, gpuToleration) } + +func TestGetReplicaCount(t *testing.T) { + mpiResourceHandler := mpiOperatorResourceHandler{} + tfObj := dummyMPICustomObj(1, 1, 0) + taskTemplate := dummyMPITaskTemplate("the job", tfObj) + resource, err := mpiResourceHandler.BuildResource(context.TODO(), dummyMPITaskContext(taskTemplate, resourceRequirements, nil)) + assert.NoError(t, err) + assert.NotNil(t, resource) + MPIJob, ok := resource.(*kubeflowv1.MPIJob) + assert.True(t, ok) + + assert.NotNil(t, common.GetReplicaCount(MPIJob.Spec.MPIReplicaSpecs, kubeflowv1.MPIJobReplicaTypeWorker)) + assert.NotNil(t, common.GetReplicaCount(MPIJob.Spec.MPIReplicaSpecs, kubeflowv1.MPIJobReplicaTypeLauncher)) +} diff --git a/flyteplugins/go/tasks/plugins/k8s/kfoperators/pytorch/pytorch.go b/flyteplugins/go/tasks/plugins/k8s/kfoperators/pytorch/pytorch.go index 81c8e16cd5..6d0bad4ecd 100644 --- a/flyteplugins/go/tasks/plugins/k8s/kfoperators/pytorch/pytorch.go +++ b/flyteplugins/go/tasks/plugins/k8s/kfoperators/pytorch/pytorch.go @@ -171,7 +171,10 @@ func ParseElasticConfig(elasticConfig ElasticConfig) *kubeflowv1.ElasticPolicy { // any operations that might take a long time (limits are configured system-wide) should be offloaded to the // background. func (pytorchOperatorResourceHandler) GetTaskPhase(_ context.Context, pluginContext k8s.PluginContext, resource client.Object) (pluginsCore.PhaseInfo, error) { - app := resource.(*kubeflowv1.PyTorchJob) + app, ok := resource.(*kubeflowv1.PyTorchJob) + if !ok { + return pluginsCore.PhaseInfoUndefined, fmt.Errorf("failed to convert resource data type") + } // Elastic PytorchJobs don't use master replicas hasMaster := false @@ -179,7 +182,7 @@ func (pytorchOperatorResourceHandler) GetTaskPhase(_ context.Context, pluginCont hasMaster = true } - workersCount := app.Spec.PyTorchReplicaSpecs[kubeflowv1.PyTorchJobReplicaTypeWorker].Replicas + workersCount := common.GetReplicaCount(app.Spec.PyTorchReplicaSpecs, kubeflowv1.PyTorchJobReplicaTypeWorker) taskLogs, err := common.GetLogs(pluginContext, common.PytorchTaskType, app.ObjectMeta, hasMaster, *workersCount, 0, 0, 0) if err != nil { diff --git a/flyteplugins/go/tasks/plugins/k8s/kfoperators/pytorch/pytorch_test.go b/flyteplugins/go/tasks/plugins/k8s/kfoperators/pytorch/pytorch_test.go index f0e215f262..e0606b1020 100644 --- a/flyteplugins/go/tasks/plugins/k8s/kfoperators/pytorch/pytorch_test.go +++ b/flyteplugins/go/tasks/plugins/k8s/kfoperators/pytorch/pytorch_test.go @@ -959,3 +959,16 @@ func TestParseElasticConfig(t *testing.T) { assert.Equal(t, int32(4), *elasticPolicy.NProcPerNode) assert.Equal(t, kubeflowv1.RDZVBackend("c10d"), *elasticPolicy.RDZVBackend) } + +func TestGetReplicaCount(t *testing.T) { + pytorchResourceHandler := pytorchOperatorResourceHandler{} + tfObj := dummyPytorchCustomObj(1) + taskTemplate := dummyPytorchTaskTemplate("the job", tfObj) + resource, err := pytorchResourceHandler.BuildResource(context.TODO(), dummyPytorchTaskContext(taskTemplate, resourceRequirements, nil)) + assert.NoError(t, err) + assert.NotNil(t, resource) + PytorchJob, ok := resource.(*kubeflowv1.PyTorchJob) + assert.True(t, ok) + + assert.NotNil(t, common.GetReplicaCount(PytorchJob.Spec.PyTorchReplicaSpecs, kubeflowv1.PyTorchJobReplicaTypeWorker)) +} diff --git a/flyteplugins/go/tasks/plugins/k8s/kfoperators/tensorflow/tensorflow.go b/flyteplugins/go/tasks/plugins/k8s/kfoperators/tensorflow/tensorflow.go index f44b550ede..db5fe6a83a 100644 --- a/flyteplugins/go/tasks/plugins/k8s/kfoperators/tensorflow/tensorflow.go +++ b/flyteplugins/go/tasks/plugins/k8s/kfoperators/tensorflow/tensorflow.go @@ -139,24 +139,19 @@ func (tensorflowOperatorResourceHandler) BuildResource(ctx context.Context, task return job, nil } -func getReplicaCount(specs map[commonOp.ReplicaType]*commonOp.ReplicaSpec, replicaType commonOp.ReplicaType) *int32 { - if spec, ok := specs[replicaType]; ok && spec.Replicas != nil { - return spec.Replicas - } - - return new(int32) // return 0 as default value -} - // Analyses the k8s resource and reports the status as TaskPhase. This call is expected to be relatively fast, // any operations that might take a long time (limits are configured system-wide) should be offloaded to the // background. func (tensorflowOperatorResourceHandler) GetTaskPhase(_ context.Context, pluginContext k8s.PluginContext, resource client.Object) (pluginsCore.PhaseInfo, error) { - app := resource.(*kubeflowv1.TFJob) + app, ok := resource.(*kubeflowv1.TFJob) + if !ok { + return pluginsCore.PhaseInfoUndefined, fmt.Errorf("failed to convert resource data type") + } - workersCount := getReplicaCount(app.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeWorker) - psReplicasCount := getReplicaCount(app.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypePS) - chiefCount := getReplicaCount(app.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeChief) - evaluatorReplicasCount := getReplicaCount(app.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeEval) + workersCount := common.GetReplicaCount(app.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeWorker) + psReplicasCount := common.GetReplicaCount(app.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypePS) + chiefCount := common.GetReplicaCount(app.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeChief) + evaluatorReplicasCount := common.GetReplicaCount(app.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeEval) taskLogs, err := common.GetLogs(pluginContext, common.TensorflowTaskType, app.ObjectMeta, false, *workersCount, *psReplicasCount, *chiefCount, *evaluatorReplicasCount) diff --git a/flyteplugins/go/tasks/plugins/k8s/kfoperators/tensorflow/tensorflow_test.go b/flyteplugins/go/tasks/plugins/k8s/kfoperators/tensorflow/tensorflow_test.go index 7b694ad9d9..c3252183fc 100644 --- a/flyteplugins/go/tasks/plugins/k8s/kfoperators/tensorflow/tensorflow_test.go +++ b/flyteplugins/go/tasks/plugins/k8s/kfoperators/tensorflow/tensorflow_test.go @@ -305,10 +305,10 @@ func TestGetReplicaCount(t *testing.T) { tensorflowJob, ok := resource.(*kubeflowv1.TFJob) assert.True(t, ok) - assert.NotNil(t, getReplicaCount(tensorflowJob.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeWorker)) - assert.NotNil(t, getReplicaCount(tensorflowJob.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypePS)) - assert.NotNil(t, getReplicaCount(tensorflowJob.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeChief)) - assert.NotNil(t, getReplicaCount(tensorflowJob.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeEval)) + assert.NotNil(t, common.GetReplicaCount(tensorflowJob.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeWorker)) + assert.NotNil(t, common.GetReplicaCount(tensorflowJob.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypePS)) + assert.NotNil(t, common.GetReplicaCount(tensorflowJob.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeChief)) + assert.NotNil(t, common.GetReplicaCount(tensorflowJob.Spec.TFReplicaSpecs, kubeflowv1.TFJobReplicaTypeEval)) } func TestBuildResourceTensorFlow(t *testing.T) { From 475e9d07644c612150f09598cf1b5eef1f1fa640 Mon Sep 17 00:00:00 2001 From: Kevin Su Date: Mon, 4 Dec 2023 18:32:36 -0800 Subject: [PATCH 05/19] Add LogLinks to taskInfo for agent (#4529) Signed-off-by: Kevin Su --- .../gen/pb-cpp/flyteidl/admin/agent.pb.cc | 154 +++-- flyteidl/gen/pb-cpp/flyteidl/admin/agent.pb.h | 41 ++ flyteidl/gen/pb-go/flyteidl/admin/agent.pb.go | 115 ++-- .../pb-go/flyteidl/admin/agent.pb.validate.go | 15 + .../pb-go/flyteidl/service/agent.swagger.json | 34 ++ .../gen/pb-java/flyteidl/admin/Agent.java | 555 ++++++++++++++++-- flyteidl/gen/pb-js/flyteidl.d.ts | 6 + flyteidl/gen/pb-js/flyteidl.js | 27 + .../gen/pb_python/flyteidl/admin/agent_pb2.py | 51 +- .../pb_python/flyteidl/admin/agent_pb2.pyi | 9 +- flyteidl/gen/pb_rust/flyteidl.admin.rs | 3 + flyteidl/protos/flyteidl/admin/agent.proto | 3 + .../go/tasks/plugins/webapi/agent/plugin.go | 16 +- .../tasks/plugins/webapi/agent/plugin_test.go | 36 +- 14 files changed, 886 insertions(+), 179 deletions(-) diff --git a/flyteidl/gen/pb-cpp/flyteidl/admin/agent.pb.cc b/flyteidl/gen/pb-cpp/flyteidl/admin/agent.pb.cc index e4e12e3543..ec842a83aa 100644 --- a/flyteidl/gen/pb-cpp/flyteidl/admin/agent.pb.cc +++ b/flyteidl/gen/pb-cpp/flyteidl/admin/agent.pb.cc @@ -21,6 +21,7 @@ extern PROTOBUF_INTERNAL_EXPORT_flyteidl_2fadmin_2fagent_2eproto ::google::proto extern PROTOBUF_INTERNAL_EXPORT_flyteidl_2fadmin_2fagent_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_TaskExecutionMetadata_LabelsEntry_DoNotUse_flyteidl_2fadmin_2fagent_2eproto; extern PROTOBUF_INTERNAL_EXPORT_flyteidl_2fadmin_2fagent_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Resource_flyteidl_2fadmin_2fagent_2eproto; extern PROTOBUF_INTERNAL_EXPORT_flyteidl_2fadmin_2fagent_2eproto ::google::protobuf::internal::SCCInfo<4> scc_info_TaskExecutionMetadata_flyteidl_2fadmin_2fagent_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_flyteidl_2fcore_2fexecution_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_TaskLog_flyteidl_2fcore_2fexecution_2eproto; extern PROTOBUF_INTERNAL_EXPORT_flyteidl_2fcore_2fidentifier_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_TaskExecutionIdentifier_flyteidl_2fcore_2fidentifier_2eproto; extern PROTOBUF_INTERNAL_EXPORT_flyteidl_2fcore_2fliterals_2eproto ::google::protobuf::internal::SCCInfo<9> scc_info_Literal_flyteidl_2fcore_2fliterals_2eproto; extern PROTOBUF_INTERNAL_EXPORT_flyteidl_2fcore_2ftasks_2eproto ::google::protobuf::internal::SCCInfo<10> scc_info_TaskTemplate_flyteidl_2fcore_2ftasks_2eproto; @@ -185,9 +186,10 @@ static void InitDefaultsGetTaskResponse_flyteidl_2fadmin_2fagent_2eproto() { ::flyteidl::admin::GetTaskResponse::InitAsDefaultInstance(); } -::google::protobuf::internal::SCCInfo<1> scc_info_GetTaskResponse_flyteidl_2fadmin_2fagent_2eproto = - {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsGetTaskResponse_flyteidl_2fadmin_2fagent_2eproto}, { - &scc_info_Resource_flyteidl_2fadmin_2fagent_2eproto.base,}}; +::google::protobuf::internal::SCCInfo<2> scc_info_GetTaskResponse_flyteidl_2fadmin_2fagent_2eproto = + {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsGetTaskResponse_flyteidl_2fadmin_2fagent_2eproto}, { + &scc_info_Resource_flyteidl_2fadmin_2fagent_2eproto.base, + &scc_info_TaskLog_flyteidl_2fcore_2fexecution_2eproto.base,}}; static void InitDefaultsResource_flyteidl_2fadmin_2fagent_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; @@ -317,6 +319,7 @@ const ::google::protobuf::uint32 TableStruct_flyteidl_2fadmin_2fagent_2eproto::o ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ PROTOBUF_FIELD_OFFSET(::flyteidl::admin::GetTaskResponse, resource_), + PROTOBUF_FIELD_OFFSET(::flyteidl::admin::GetTaskResponse, log_links_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(::flyteidl::admin::Resource, _internal_metadata_), ~0u, // no _extensions_ @@ -347,9 +350,9 @@ static const ::google::protobuf::internal::MigrationSchema schemas[] PROTOBUF_SE { 47, -1, sizeof(::flyteidl::admin::CreateTaskResponse)}, { 53, -1, sizeof(::flyteidl::admin::GetTaskRequest)}, { 60, -1, sizeof(::flyteidl::admin::GetTaskResponse)}, - { 66, -1, sizeof(::flyteidl::admin::Resource)}, - { 74, -1, sizeof(::flyteidl::admin::DeleteTaskRequest)}, - { 81, -1, sizeof(::flyteidl::admin::DeleteTaskResponse)}, + { 67, -1, sizeof(::flyteidl::admin::Resource)}, + { 75, -1, sizeof(::flyteidl::admin::DeleteTaskRequest)}, + { 82, -1, sizeof(::flyteidl::admin::DeleteTaskResponse)}, }; static ::google::protobuf::Message const * const file_default_instances[] = { @@ -377,55 +380,57 @@ const char descriptor_table_protodef_flyteidl_2fadmin_2fagent_2eproto[] = "dmin\032\034flyteidl/core/literals.proto\032\031flyt" "eidl/core/tasks.proto\032\035flyteidl/core/int" "erface.proto\032\036flyteidl/core/identifier.p" - "roto\"\232\004\n\025TaskExecutionMetadata\022A\n\021task_e" - "xecution_id\030\001 \001(\0132&.flyteidl.core.TaskEx" - "ecutionIdentifier\022\021\n\tnamespace\030\002 \001(\t\022A\n\006" - "labels\030\003 \003(\01321.flyteidl.admin.TaskExecut" - "ionMetadata.LabelsEntry\022K\n\013annotations\030\004" - " \003(\01326.flyteidl.admin.TaskExecutionMetad" - "ata.AnnotationsEntry\022\033\n\023k8s_service_acco" - "unt\030\005 \001(\t\022^\n\025environment_variables\030\006 \003(\013" - "2\?.flyteidl.admin.TaskExecutionMetadata." - "EnvironmentVariablesEntry\032-\n\013LabelsEntry" - "\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\0322\n\020Anno" - "tationsEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t" - ":\0028\001\032;\n\031EnvironmentVariablesEntry\022\013\n\003key" - "\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"\314\001\n\021CreateTask" - "Request\022)\n\006inputs\030\001 \001(\0132\031.flyteidl.core." - "LiteralMap\022-\n\010template\030\002 \001(\0132\033.flyteidl." - "core.TaskTemplate\022\025\n\routput_prefix\030\003 \001(\t" - "\022F\n\027task_execution_metadata\030\004 \001(\0132%.flyt" - "eidl.admin.TaskExecutionMetadata\"+\n\022Crea" - "teTaskResponse\022\025\n\rresource_meta\030\001 \001(\014\":\n" - "\016GetTaskRequest\022\021\n\ttask_type\030\001 \001(\t\022\025\n\rre" - "source_meta\030\002 \001(\014\"=\n\017GetTaskResponse\022*\n\010" - "resource\030\001 \001(\0132\030.flyteidl.admin.Resource" - "\"m\n\010Resource\022$\n\005state\030\001 \001(\0162\025.flyteidl.a" - "dmin.State\022*\n\007outputs\030\002 \001(\0132\031.flyteidl.c" - "ore.LiteralMap\022\017\n\007message\030\003 \001(\t\"=\n\021Delet" - "eTaskRequest\022\021\n\ttask_type\030\001 \001(\t\022\025\n\rresou" - "rce_meta\030\002 \001(\014\"\024\n\022DeleteTaskResponse*^\n\005" - "State\022\025\n\021RETRYABLE_FAILURE\020\000\022\025\n\021PERMANEN" - "T_FAILURE\020\001\022\013\n\007PENDING\020\002\022\013\n\007RUNNING\020\003\022\r\n" - "\tSUCCEEDED\020\004B=Z;github.com/flyteorg/flyt" - "e/flyteidl/gen/pb-go/flyteidl/adminb\006pro" - "to3" + "roto\032\035flyteidl/core/execution.proto\"\232\004\n\025" + "TaskExecutionMetadata\022A\n\021task_execution_" + "id\030\001 \001(\0132&.flyteidl.core.TaskExecutionId" + "entifier\022\021\n\tnamespace\030\002 \001(\t\022A\n\006labels\030\003 " + "\003(\01321.flyteidl.admin.TaskExecutionMetada" + "ta.LabelsEntry\022K\n\013annotations\030\004 \003(\01326.fl" + "yteidl.admin.TaskExecutionMetadata.Annot" + "ationsEntry\022\033\n\023k8s_service_account\030\005 \001(\t" + "\022^\n\025environment_variables\030\006 \003(\0132\?.flytei" + "dl.admin.TaskExecutionMetadata.Environme" + "ntVariablesEntry\032-\n\013LabelsEntry\022\013\n\003key\030\001" + " \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\0322\n\020AnnotationsEn" + "try\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\032;\n\031E" + "nvironmentVariablesEntry\022\013\n\003key\030\001 \001(\t\022\r\n" + "\005value\030\002 \001(\t:\0028\001\"\314\001\n\021CreateTaskRequest\022)" + "\n\006inputs\030\001 \001(\0132\031.flyteidl.core.LiteralMa" + "p\022-\n\010template\030\002 \001(\0132\033.flyteidl.core.Task" + "Template\022\025\n\routput_prefix\030\003 \001(\t\022F\n\027task_" + "execution_metadata\030\004 \001(\0132%.flyteidl.admi" + "n.TaskExecutionMetadata\"+\n\022CreateTaskRes" + "ponse\022\025\n\rresource_meta\030\001 \001(\014\":\n\016GetTaskR" + "equest\022\021\n\ttask_type\030\001 \001(\t\022\025\n\rresource_me" + "ta\030\002 \001(\014\"h\n\017GetTaskResponse\022*\n\010resource\030" + "\001 \001(\0132\030.flyteidl.admin.Resource\022)\n\tlog_l" + "inks\030\002 \003(\0132\026.flyteidl.core.TaskLog\"m\n\010Re" + "source\022$\n\005state\030\001 \001(\0162\025.flyteidl.admin.S" + "tate\022*\n\007outputs\030\002 \001(\0132\031.flyteidl.core.Li" + "teralMap\022\017\n\007message\030\003 \001(\t\"=\n\021DeleteTaskR" + "equest\022\021\n\ttask_type\030\001 \001(\t\022\025\n\rresource_me" + "ta\030\002 \001(\014\"\024\n\022DeleteTaskResponse*^\n\005State\022" + "\025\n\021RETRYABLE_FAILURE\020\000\022\025\n\021PERMANENT_FAIL" + "URE\020\001\022\013\n\007PENDING\020\002\022\013\n\007RUNNING\020\003\022\r\n\tSUCCE" + "EDED\020\004B=Z;github.com/flyteorg/flyte/flyt" + "eidl/gen/pb-go/flyteidl/adminb\006proto3" ; ::google::protobuf::internal::DescriptorTable descriptor_table_flyteidl_2fadmin_2fagent_2eproto = { false, InitDefaults_flyteidl_2fadmin_2fagent_2eproto, descriptor_table_protodef_flyteidl_2fadmin_2fagent_2eproto, - "flyteidl/admin/agent.proto", &assign_descriptors_table_flyteidl_2fadmin_2fagent_2eproto, 1443, + "flyteidl/admin/agent.proto", &assign_descriptors_table_flyteidl_2fadmin_2fagent_2eproto, 1517, }; void AddDescriptors_flyteidl_2fadmin_2fagent_2eproto() { - static constexpr ::google::protobuf::internal::InitFunc deps[4] = + static constexpr ::google::protobuf::internal::InitFunc deps[5] = { ::AddDescriptors_flyteidl_2fcore_2fliterals_2eproto, ::AddDescriptors_flyteidl_2fcore_2ftasks_2eproto, ::AddDescriptors_flyteidl_2fcore_2finterface_2eproto, ::AddDescriptors_flyteidl_2fcore_2fidentifier_2eproto, + ::AddDescriptors_flyteidl_2fcore_2fexecution_2eproto, }; - ::google::protobuf::internal::AddDescriptors(&descriptor_table_flyteidl_2fadmin_2fagent_2eproto, deps, 4); + ::google::protobuf::internal::AddDescriptors(&descriptor_table_flyteidl_2fadmin_2fagent_2eproto, deps, 5); } // Force running AddDescriptors() at dynamic initialization time. @@ -2668,8 +2673,12 @@ const ::flyteidl::admin::Resource& GetTaskResponse::HasBitSetters::resource(const GetTaskResponse* msg) { return *msg->resource_; } +void GetTaskResponse::clear_log_links() { + log_links_.Clear(); +} #if !defined(_MSC_VER) || _MSC_VER >= 1900 const int GetTaskResponse::kResourceFieldNumber; +const int GetTaskResponse::kLogLinksFieldNumber; #endif // !defined(_MSC_VER) || _MSC_VER >= 1900 GetTaskResponse::GetTaskResponse() @@ -2679,7 +2688,8 @@ GetTaskResponse::GetTaskResponse() } GetTaskResponse::GetTaskResponse(const GetTaskResponse& from) : ::google::protobuf::Message(), - _internal_metadata_(nullptr) { + _internal_metadata_(nullptr), + log_links_(from.log_links_) { _internal_metadata_.MergeFrom(from._internal_metadata_); if (from.has_resource()) { resource_ = new ::flyteidl::admin::Resource(*from.resource_); @@ -2719,6 +2729,7 @@ void GetTaskResponse::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; + log_links_.Clear(); if (GetArenaNoVirtual() == nullptr && resource_ != nullptr) { delete resource_; } @@ -2752,6 +2763,22 @@ const char* GetTaskResponse::_InternalParse(const char* begin, const char* end, {parser_till_end, object}, ptr - size, ptr)); break; } + // repeated .flyteidl.core.TaskLog log_links = 2; + case 2: { + if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual; + do { + ptr = ::google::protobuf::io::ReadSize(ptr, &size); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + parser_till_end = ::flyteidl::core::TaskLog::_InternalParse; + object = msg->add_log_links(); + if (size > end - ptr) goto len_delim_till_end; + ptr += size; + GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange( + {parser_till_end, object}, ptr - size, ptr)); + if (ptr >= end) break; + } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1)); + break; + } default: { handle_unusual: if ((tag & 7) == 4 || tag == 0) { @@ -2793,6 +2820,17 @@ bool GetTaskResponse::MergePartialFromCodedStream( break; } + // repeated .flyteidl.core.TaskLog log_links = 2; + case 2: { + if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessage( + input, add_log_links())); + } else { + goto handle_unusual; + } + break; + } + default: { handle_unusual: if (tag == 0) { @@ -2826,6 +2864,15 @@ void GetTaskResponse::SerializeWithCachedSizes( 1, HasBitSetters::resource(this), output); } + // repeated .flyteidl.core.TaskLog log_links = 2; + for (unsigned int i = 0, + n = static_cast(this->log_links_size()); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, + this->log_links(static_cast(i)), + output); + } + if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( _internal_metadata_.unknown_fields(), output); @@ -2846,6 +2893,14 @@ ::google::protobuf::uint8* GetTaskResponse::InternalSerializeWithCachedSizesToAr 1, HasBitSetters::resource(this), target); } + // repeated .flyteidl.core.TaskLog log_links = 2; + for (unsigned int i = 0, + n = static_cast(this->log_links_size()); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + InternalWriteMessageToArray( + 2, this->log_links(static_cast(i)), target); + } + if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields(), target); @@ -2867,6 +2922,17 @@ size_t GetTaskResponse::ByteSizeLong() const { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; + // repeated .flyteidl.core.TaskLog log_links = 2; + { + unsigned int count = static_cast(this->log_links_size()); + total_size += 1UL * count; + for (unsigned int i = 0; i < count; i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSize( + this->log_links(static_cast(i))); + } + } + // .flyteidl.admin.Resource resource = 1; if (this->has_resource()) { total_size += 1 + @@ -2901,6 +2967,7 @@ void GetTaskResponse::MergeFrom(const GetTaskResponse& from) { ::google::protobuf::uint32 cached_has_bits = 0; (void) cached_has_bits; + log_links_.MergeFrom(from.log_links_); if (from.has_resource()) { mutable_resource()->::flyteidl::admin::Resource::MergeFrom(from.resource()); } @@ -2931,6 +2998,7 @@ void GetTaskResponse::Swap(GetTaskResponse* other) { void GetTaskResponse::InternalSwap(GetTaskResponse* other) { using std::swap; _internal_metadata_.Swap(&other->_internal_metadata_); + CastToBase(&log_links_)->InternalSwap(CastToBase(&other->log_links_)); swap(resource_, other->resource_); } diff --git a/flyteidl/gen/pb-cpp/flyteidl/admin/agent.pb.h b/flyteidl/gen/pb-cpp/flyteidl/admin/agent.pb.h index 5d43236ad3..6c44bf09f8 100644 --- a/flyteidl/gen/pb-cpp/flyteidl/admin/agent.pb.h +++ b/flyteidl/gen/pb-cpp/flyteidl/admin/agent.pb.h @@ -39,6 +39,7 @@ #include "flyteidl/core/tasks.pb.h" #include "flyteidl/core/interface.pb.h" #include "flyteidl/core/identifier.pb.h" +#include "flyteidl/core/execution.pb.h" // @@protoc_insertion_point(includes) #include #define PROTOBUF_INTERNAL_EXPORT_flyteidl_2fadmin_2fagent_2eproto @@ -900,6 +901,18 @@ class GetTaskResponse final : // accessors ------------------------------------------------------- + // repeated .flyteidl.core.TaskLog log_links = 2; + int log_links_size() const; + void clear_log_links(); + static const int kLogLinksFieldNumber = 2; + ::flyteidl::core::TaskLog* mutable_log_links(int index); + ::google::protobuf::RepeatedPtrField< ::flyteidl::core::TaskLog >* + mutable_log_links(); + const ::flyteidl::core::TaskLog& log_links(int index) const; + ::flyteidl::core::TaskLog* add_log_links(); + const ::google::protobuf::RepeatedPtrField< ::flyteidl::core::TaskLog >& + log_links() const; + // .flyteidl.admin.Resource resource = 1; bool has_resource() const; void clear_resource(); @@ -914,6 +927,7 @@ class GetTaskResponse final : class HasBitSetters; ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::RepeatedPtrField< ::flyteidl::core::TaskLog > log_links_; ::flyteidl::admin::Resource* resource_; mutable ::google::protobuf::internal::CachedSize _cached_size_; friend struct ::TableStruct_flyteidl_2fadmin_2fagent_2eproto; @@ -1937,6 +1951,33 @@ inline void GetTaskResponse::set_allocated_resource(::flyteidl::admin::Resource* // @@protoc_insertion_point(field_set_allocated:flyteidl.admin.GetTaskResponse.resource) } +// repeated .flyteidl.core.TaskLog log_links = 2; +inline int GetTaskResponse::log_links_size() const { + return log_links_.size(); +} +inline ::flyteidl::core::TaskLog* GetTaskResponse::mutable_log_links(int index) { + // @@protoc_insertion_point(field_mutable:flyteidl.admin.GetTaskResponse.log_links) + return log_links_.Mutable(index); +} +inline ::google::protobuf::RepeatedPtrField< ::flyteidl::core::TaskLog >* +GetTaskResponse::mutable_log_links() { + // @@protoc_insertion_point(field_mutable_list:flyteidl.admin.GetTaskResponse.log_links) + return &log_links_; +} +inline const ::flyteidl::core::TaskLog& GetTaskResponse::log_links(int index) const { + // @@protoc_insertion_point(field_get:flyteidl.admin.GetTaskResponse.log_links) + return log_links_.Get(index); +} +inline ::flyteidl::core::TaskLog* GetTaskResponse::add_log_links() { + // @@protoc_insertion_point(field_add:flyteidl.admin.GetTaskResponse.log_links) + return log_links_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::flyteidl::core::TaskLog >& +GetTaskResponse::log_links() const { + // @@protoc_insertion_point(field_list:flyteidl.admin.GetTaskResponse.log_links) + return log_links_; +} + // ------------------------------------------------------------------- // Resource diff --git a/flyteidl/gen/pb-go/flyteidl/admin/agent.pb.go b/flyteidl/gen/pb-go/flyteidl/admin/agent.pb.go index 7511d46559..e070c2e85e 100644 --- a/flyteidl/gen/pb-go/flyteidl/admin/agent.pb.go +++ b/flyteidl/gen/pb-go/flyteidl/admin/agent.pb.go @@ -305,10 +305,12 @@ func (m *GetTaskRequest) GetResourceMeta() []byte { // Response to get an individual task resource. type GetTaskResponse struct { - Resource *Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Resource *Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` + // log information for the task execution. + LogLinks []*core.TaskLog `protobuf:"bytes,2,rep,name=log_links,json=logLinks,proto3" json:"log_links,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *GetTaskResponse) Reset() { *m = GetTaskResponse{} } @@ -343,6 +345,13 @@ func (m *GetTaskResponse) GetResource() *Resource { return nil } +func (m *GetTaskResponse) GetLogLinks() []*core.TaskLog { + if m != nil { + return m.LogLinks + } + return nil +} + type Resource struct { // The state of the execution is used to control its visibility in the UI/CLI. State State `protobuf:"varint,1,opt,name=state,proto3,enum=flyteidl.admin.State" json:"state,omitempty"` @@ -503,52 +512,54 @@ func init() { func init() { proto.RegisterFile("flyteidl/admin/agent.proto", fileDescriptor_c434e52bb0028071) } var fileDescriptor_c434e52bb0028071 = []byte{ - // 740 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x7f, 0x6b, 0x2a, 0x47, - 0x14, 0xad, 0x1a, 0x8d, 0x5e, 0xf3, 0x43, 0xa7, 0x91, 0x6e, 0x4c, 0x5a, 0x82, 0xa5, 0x25, 0xb4, - 0x74, 0x25, 0xa6, 0xb4, 0x49, 0x4b, 0x5b, 0x4c, 0xdc, 0x8a, 0x60, 0x24, 0x4c, 0xb4, 0xb4, 0x85, - 0x56, 0xc6, 0xf5, 0xea, 0x5b, 0x5c, 0x67, 0xf7, 0xed, 0xcc, 0x4a, 0xfc, 0xfb, 0xc1, 0xfb, 0x0c, - 0xef, 0xe3, 0x3e, 0x76, 0xf6, 0x47, 0x54, 0x7c, 0x8f, 0x84, 0xf7, 0xdf, 0xce, 0x3d, 0xf7, 0x9e, - 0x39, 0x73, 0xce, 0x2c, 0x03, 0xd5, 0x89, 0xbd, 0x94, 0x68, 0x8d, 0xed, 0x3a, 0x1b, 0xcf, 0x2d, - 0x5e, 0x67, 0x53, 0xe4, 0x52, 0x77, 0x3d, 0x47, 0x3a, 0xe4, 0x20, 0xc6, 0x74, 0x85, 0x55, 0x4f, - 0x93, 0x5e, 0xd3, 0xf1, 0xb0, 0x6e, 0x5b, 0x12, 0x3d, 0x66, 0x8b, 0xb0, 0xbb, 0x7a, 0xbc, 0x8e, - 0x4a, 0x26, 0x66, 0x31, 0xf4, 0xe5, 0x3a, 0x64, 0x71, 0x89, 0xde, 0x84, 0x99, 0x18, 0xc1, 0x5f, - 0x6d, 0xc0, 0x63, 0xe4, 0xd2, 0x9a, 0x58, 0xe8, 0x85, 0x78, 0xed, 0x5d, 0x16, 0x2a, 0x7d, 0x26, - 0x66, 0xc6, 0x23, 0x9a, 0xbe, 0xb4, 0x1c, 0x7e, 0x87, 0x92, 0x8d, 0x99, 0x64, 0x84, 0x42, 0x39, - 0xd8, 0x67, 0x88, 0x31, 0x32, 0xb4, 0xc6, 0x5a, 0xea, 0x2c, 0x75, 0x5e, 0x6c, 0x7c, 0xab, 0x27, - 0xea, 0x03, 0x56, 0x7d, 0x8d, 0xa0, 0x93, 0x6c, 0x41, 0x0f, 0xe5, 0x3a, 0x40, 0x4e, 0xa1, 0xc0, - 0xd9, 0x1c, 0x85, 0xcb, 0x4c, 0xd4, 0xd2, 0x67, 0xa9, 0xf3, 0x02, 0x7d, 0x2a, 0x90, 0x0e, 0xe4, - 0x6c, 0x36, 0x42, 0x5b, 0x68, 0x99, 0xb3, 0xcc, 0x79, 0xb1, 0x71, 0xa1, 0xaf, 0x9b, 0xa4, 0x6f, - 0x15, 0xaa, 0x77, 0xd5, 0x8c, 0xc1, 0xa5, 0xb7, 0xa4, 0x11, 0x01, 0xf9, 0x1b, 0x8a, 0x8c, 0x73, - 0x47, 0xb2, 0xa0, 0x53, 0x68, 0x3b, 0x8a, 0xef, 0xa7, 0xe7, 0xf1, 0x35, 0x9f, 0x06, 0x43, 0xd2, - 0x55, 0x2a, 0xa2, 0xc3, 0xe7, 0xb3, 0x2b, 0x31, 0x14, 0xe8, 0x2d, 0x2c, 0x13, 0x87, 0xcc, 0x34, - 0x1d, 0x9f, 0x4b, 0x2d, 0xab, 0x0e, 0x53, 0x9e, 0x5d, 0x89, 0x87, 0x10, 0x69, 0x86, 0x00, 0x91, - 0x50, 0x41, 0xbe, 0xb0, 0x3c, 0x87, 0xcf, 0x91, 0xcb, 0xe1, 0x82, 0x79, 0x16, 0x1b, 0xd9, 0x28, - 0xb4, 0x9c, 0xd2, 0xf4, 0xc7, 0xf3, 0x34, 0x19, 0x4f, 0x14, 0x7f, 0xc5, 0x0c, 0xa1, 0xb8, 0x23, - 0xdc, 0x02, 0x55, 0xaf, 0xa1, 0xb8, 0x62, 0x0b, 0x29, 0x41, 0x66, 0x86, 0x4b, 0x95, 0x5e, 0x81, - 0x06, 0x9f, 0xe4, 0x08, 0xb2, 0x0b, 0x66, 0xfb, 0x71, 0x0a, 0xe1, 0xe2, 0x97, 0xf4, 0x55, 0xaa, - 0xfa, 0x3b, 0x94, 0x36, 0x1d, 0x78, 0xd1, 0x7c, 0x1b, 0x8e, 0x3f, 0xa8, 0xf6, 0x25, 0x44, 0xb5, - 0x37, 0x69, 0x28, 0xdf, 0x7a, 0xc8, 0x24, 0x06, 0x9e, 0x50, 0x7c, 0xed, 0xa3, 0x90, 0xe4, 0x02, - 0x72, 0x16, 0x77, 0x7d, 0x29, 0xa2, 0xbb, 0x78, 0xbc, 0x71, 0x17, 0xbb, 0xe1, 0x9f, 0x73, 0xc7, - 0x5c, 0x1a, 0x35, 0x92, 0x9f, 0x21, 0x2f, 0x71, 0xee, 0xda, 0x4c, 0x86, 0xbb, 0x14, 0x1b, 0x27, - 0x5b, 0x2e, 0x70, 0x3f, 0x6a, 0xa1, 0x49, 0x33, 0xf9, 0x1a, 0xf6, 0x1d, 0x5f, 0xba, 0xbe, 0x1c, - 0xba, 0x1e, 0x4e, 0xac, 0x47, 0x2d, 0xa3, 0x34, 0xee, 0x85, 0xc5, 0x7b, 0x55, 0x23, 0xff, 0xc1, - 0x17, 0x1b, 0xff, 0xc9, 0x3c, 0x4a, 0x4d, 0xdb, 0x51, 0x9b, 0x7d, 0xf3, 0xac, 0x88, 0x69, 0x45, - 0x6e, 0x2b, 0xd7, 0xae, 0x81, 0xac, 0x9a, 0x20, 0x5c, 0x87, 0x0b, 0xa5, 0xcc, 0x43, 0xe1, 0xf8, - 0x9e, 0x89, 0x6a, 0x3b, 0x65, 0xc6, 0x1e, 0xdd, 0x8b, 0x8b, 0xc1, 0x78, 0x8d, 0xc2, 0x41, 0x1b, - 0xe5, 0xaa, 0x79, 0x27, 0x50, 0x50, 0x5a, 0xe5, 0xd2, 0xc5, 0x28, 0x84, 0x7c, 0x50, 0xe8, 0x2f, - 0xdd, 0x2d, 0x9c, 0xe9, 0x2d, 0x9c, 0x6d, 0x38, 0x4c, 0x38, 0x23, 0x2d, 0x3f, 0x42, 0x3e, 0x6e, - 0x89, 0x32, 0xd1, 0x36, 0x4f, 0x4c, 0x23, 0x9c, 0x26, 0x9d, 0xb5, 0xb7, 0x29, 0xc8, 0xc7, 0x65, - 0xf2, 0x3d, 0x64, 0x85, 0x0c, 0xe2, 0x09, 0xe6, 0x0f, 0x1a, 0x95, 0xcd, 0xf9, 0x87, 0x00, 0xa4, - 0x61, 0x0f, 0xb9, 0x84, 0xdd, 0x30, 0x00, 0x11, 0xa5, 0xf9, 0x91, 0x2b, 0x10, 0x77, 0x12, 0x0d, - 0x76, 0xe7, 0x28, 0x04, 0x9b, 0x62, 0x14, 0x62, 0xbc, 0xac, 0x0d, 0xa0, 0xdc, 0x42, 0x1b, 0xd7, - 0x6f, 0xd9, 0xa7, 0x1b, 0x75, 0x04, 0x64, 0x95, 0x36, 0xf4, 0xea, 0xbb, 0xff, 0x21, 0xab, 0xce, - 0x42, 0x2a, 0x50, 0xa6, 0x46, 0x9f, 0xfe, 0xd3, 0xbc, 0xe9, 0x1a, 0xc3, 0x3f, 0x9b, 0x9d, 0xee, - 0x80, 0x1a, 0xa5, 0xcf, 0x82, 0xf2, 0xbd, 0x41, 0xef, 0x9a, 0x3d, 0xa3, 0xd7, 0x4f, 0xca, 0x29, - 0x52, 0x84, 0xdd, 0x7b, 0xa3, 0xd7, 0xea, 0xf4, 0xda, 0xa5, 0x74, 0xb0, 0xa0, 0x83, 0x5e, 0x2f, - 0x58, 0x64, 0xc8, 0x3e, 0x14, 0x1e, 0x06, 0xb7, 0xb7, 0x86, 0xd1, 0x32, 0x5a, 0xa5, 0x9d, 0x9b, - 0xdf, 0xfe, 0xfd, 0x75, 0x6a, 0xc9, 0x57, 0xfe, 0x48, 0x37, 0x9d, 0x79, 0x5d, 0xd9, 0xe2, 0x78, - 0xd3, 0xf0, 0xa3, 0x9e, 0x3c, 0x05, 0x53, 0xe4, 0x75, 0x77, 0xf4, 0xc3, 0xd4, 0xa9, 0xaf, 0xbf, - 0x50, 0xa3, 0x9c, 0x7a, 0x14, 0x2e, 0xdf, 0x07, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x0a, 0x0e, 0xc8, - 0xba, 0x06, 0x00, 0x00, + // 773 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x7f, 0x6f, 0xe3, 0x44, + 0x10, 0x25, 0x49, 0xd3, 0x26, 0x93, 0x5e, 0x2f, 0x59, 0x1a, 0x70, 0x73, 0x07, 0xaa, 0x82, 0x40, + 0x15, 0x08, 0x47, 0xd7, 0x22, 0xe8, 0x81, 0x00, 0xe5, 0x5a, 0x53, 0x45, 0x4a, 0xa3, 0x6a, 0x9b, + 0x20, 0x40, 0x02, 0x6b, 0xe3, 0x4c, 0x8c, 0x15, 0x67, 0xd7, 0x78, 0xd7, 0xd1, 0x45, 0xe2, 0x3f, + 0x24, 0x3e, 0x03, 0x1f, 0x17, 0x79, 0xfd, 0xa3, 0x49, 0x64, 0x50, 0x4f, 0xf7, 0x9f, 0x77, 0xde, + 0x9b, 0x37, 0x6f, 0x67, 0xc6, 0x5a, 0xe8, 0xcc, 0xfd, 0xb5, 0x42, 0x6f, 0xe6, 0xf7, 0xd8, 0x6c, + 0xe9, 0xf1, 0x1e, 0x73, 0x91, 0x2b, 0x33, 0x08, 0x85, 0x12, 0xe4, 0x28, 0xc3, 0x4c, 0x8d, 0x75, + 0x9e, 0xe7, 0x5c, 0x47, 0x84, 0xd8, 0xf3, 0x3d, 0x85, 0x21, 0xf3, 0x65, 0xc2, 0xee, 0x9c, 0x6c, + 0xa3, 0x8a, 0xc9, 0x45, 0x06, 0x7d, 0xb0, 0x0d, 0x79, 0x5c, 0x61, 0x38, 0x67, 0x0e, 0xa6, 0xf0, + 0x87, 0x3b, 0xf0, 0x0c, 0xb9, 0xf2, 0xe6, 0x1e, 0x86, 0xc5, 0xe9, 0xf8, 0x1a, 0x9d, 0x48, 0x79, + 0x82, 0x27, 0x70, 0xf7, 0x9f, 0x2a, 0xb4, 0xc7, 0x4c, 0x2e, 0xac, 0x2c, 0x7e, 0x8b, 0x8a, 0xcd, + 0x98, 0x62, 0x84, 0x42, 0x2b, 0xb6, 0x61, 0xe7, 0x19, 0xb6, 0x37, 0x33, 0x4a, 0xa7, 0xa5, 0xb3, + 0xc6, 0xf9, 0x27, 0x66, 0x7e, 0xb9, 0x58, 0xd4, 0xdc, 0x12, 0x18, 0xe4, 0x0e, 0xe8, 0x53, 0xb5, + 0x0d, 0x90, 0xe7, 0x50, 0xe7, 0x6c, 0x89, 0x32, 0x60, 0x0e, 0x1a, 0xe5, 0xd3, 0xd2, 0x59, 0x9d, + 0x3e, 0x04, 0xc8, 0x00, 0xf6, 0x7d, 0x36, 0x45, 0x5f, 0x1a, 0x95, 0xd3, 0xca, 0x59, 0xe3, 0xfc, + 0x85, 0xb9, 0xdd, 0x43, 0xb3, 0xd0, 0xa8, 0x39, 0xd4, 0x39, 0x16, 0x57, 0xe1, 0x9a, 0xa6, 0x02, + 0xe4, 0x27, 0x68, 0x30, 0xce, 0x85, 0x62, 0x31, 0x53, 0x1a, 0x7b, 0x5a, 0xef, 0xcb, 0xc7, 0xe9, + 0xf5, 0x1f, 0x12, 0x13, 0xd1, 0x4d, 0x29, 0x62, 0xc2, 0xbb, 0x8b, 0x4b, 0x69, 0x4b, 0x0c, 0x57, + 0x9e, 0x83, 0x36, 0x73, 0x1c, 0x11, 0x71, 0x65, 0x54, 0xf5, 0x65, 0x5a, 0x8b, 0x4b, 0x79, 0x9f, + 0x20, 0xfd, 0x04, 0x20, 0x0a, 0xda, 0xc8, 0x57, 0x5e, 0x28, 0xf8, 0x12, 0xb9, 0xb2, 0x57, 0x2c, + 0xf4, 0xd8, 0xd4, 0x47, 0x69, 0xec, 0x6b, 0x4f, 0xdf, 0x3f, 0xce, 0x93, 0xf5, 0x20, 0xf1, 0x63, + 0xa6, 0x90, 0x98, 0x3b, 0xc6, 0x02, 0xa8, 0xf3, 0x12, 0x1a, 0x1b, 0x6d, 0x21, 0x4d, 0xa8, 0x2c, + 0x70, 0xad, 0xa7, 0x57, 0xa7, 0xf1, 0x27, 0x39, 0x86, 0xea, 0x8a, 0xf9, 0x51, 0x36, 0x85, 0xe4, + 0xf0, 0x75, 0xf9, 0xb2, 0xd4, 0xf9, 0x0e, 0x9a, 0xbb, 0x1d, 0x78, 0xa3, 0xfc, 0x1b, 0x38, 0xf9, + 0x4f, 0xb7, 0x6f, 0x22, 0xd4, 0xfd, 0xab, 0x0c, 0xad, 0xab, 0x10, 0x99, 0xc2, 0xb8, 0x27, 0x14, + 0xff, 0x88, 0x50, 0x2a, 0xf2, 0x02, 0xf6, 0x3d, 0x1e, 0x44, 0x4a, 0xa6, 0xbb, 0x78, 0xb2, 0xb3, + 0x8b, 0xc3, 0xe4, 0xc7, 0xba, 0x65, 0x01, 0x4d, 0x89, 0xe4, 0x2b, 0xa8, 0x29, 0x5c, 0x06, 0x3e, + 0x53, 0x49, 0x95, 0xc6, 0xf9, 0xb3, 0x82, 0x05, 0x1e, 0xa7, 0x14, 0x9a, 0x93, 0xc9, 0x47, 0xf0, + 0x44, 0x44, 0x2a, 0x88, 0x94, 0x1d, 0x84, 0x38, 0xf7, 0x5e, 0x1b, 0x15, 0xed, 0xf1, 0x30, 0x09, + 0xde, 0xe9, 0x18, 0xf9, 0x15, 0xde, 0xdf, 0xf9, 0x4f, 0x96, 0xe9, 0xd4, 0x8c, 0x3d, 0x5d, 0xec, + 0xe3, 0x47, 0x8d, 0x98, 0xb6, 0x55, 0x51, 0xb8, 0xfb, 0x12, 0xc8, 0x66, 0x13, 0x64, 0x20, 0xb8, + 0xd4, 0xce, 0x42, 0x94, 0x22, 0x0a, 0x1d, 0xd4, 0xe5, 0x74, 0x33, 0x0e, 0xe9, 0x61, 0x16, 0x8c, + 0xd3, 0xbb, 0x14, 0x8e, 0x6e, 0x50, 0x6d, 0x36, 0xef, 0x19, 0xd4, 0xb5, 0x57, 0xb5, 0x0e, 0x30, + 0x1d, 0x42, 0x2d, 0x0e, 0x8c, 0xd7, 0x41, 0x81, 0x66, 0xb9, 0x40, 0xf3, 0x4f, 0x78, 0x9a, 0x6b, + 0xa6, 0x5e, 0xbe, 0x80, 0x5a, 0x46, 0x49, 0x67, 0x62, 0xec, 0xde, 0x98, 0xa6, 0x38, 0xcd, 0x99, + 0xe4, 0x02, 0xea, 0xbe, 0x70, 0x6d, 0xdf, 0xe3, 0x0b, 0x69, 0x94, 0xf5, 0xbf, 0xf0, 0x5e, 0xc1, + 0x54, 0x86, 0xc2, 0xa5, 0x35, 0x5f, 0xb8, 0xc3, 0x98, 0xd7, 0xfd, 0xbb, 0x04, 0xb5, 0x4c, 0x8b, + 0x7c, 0x06, 0x55, 0xa9, 0xe2, 0x99, 0xc6, 0x45, 0x8f, 0xce, 0xdb, 0xbb, 0x45, 0xef, 0x63, 0x90, + 0x26, 0x1c, 0x72, 0x01, 0x07, 0xc9, 0xd4, 0x64, 0xba, 0x02, 0xff, 0xb3, 0x37, 0x19, 0x93, 0x18, + 0x70, 0xb0, 0x44, 0x29, 0x99, 0x8b, 0xe9, 0xe4, 0xb3, 0x63, 0x77, 0x02, 0xad, 0x6b, 0xf4, 0x71, + 0x7b, 0x35, 0xdf, 0xbe, 0xbb, 0xc7, 0x40, 0x36, 0x65, 0x93, 0x06, 0x7f, 0xfa, 0x1b, 0x54, 0xf5, + 0x5d, 0x48, 0x1b, 0x5a, 0xd4, 0x1a, 0xd3, 0x9f, 0xfb, 0xaf, 0x86, 0x96, 0xfd, 0x43, 0x7f, 0x30, + 0x9c, 0x50, 0xab, 0xf9, 0x4e, 0x1c, 0xbe, 0xb3, 0xe8, 0x6d, 0x7f, 0x64, 0x8d, 0xc6, 0x79, 0xb8, + 0x44, 0x1a, 0x70, 0x70, 0x67, 0x8d, 0xae, 0x07, 0xa3, 0x9b, 0x66, 0x39, 0x3e, 0xd0, 0xc9, 0x68, + 0x14, 0x1f, 0x2a, 0xe4, 0x09, 0xd4, 0xef, 0x27, 0x57, 0x57, 0x96, 0x75, 0x6d, 0x5d, 0x37, 0xf7, + 0x5e, 0x7d, 0xfb, 0xcb, 0x37, 0xae, 0xa7, 0x7e, 0x8f, 0xa6, 0xa6, 0x23, 0x96, 0x3d, 0xdd, 0x16, + 0x11, 0xba, 0xc9, 0x47, 0x2f, 0x7f, 0x3e, 0x5c, 0xe4, 0xbd, 0x60, 0xfa, 0xb9, 0x2b, 0x7a, 0xdb, + 0xaf, 0xde, 0x74, 0x5f, 0xbf, 0x24, 0x17, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x8d, 0xa5, + 0xb7, 0x0e, 0x07, 0x00, 0x00, } diff --git a/flyteidl/gen/pb-go/flyteidl/admin/agent.pb.validate.go b/flyteidl/gen/pb-go/flyteidl/admin/agent.pb.validate.go index 7efab6b18a..221003b999 100644 --- a/flyteidl/gen/pb-go/flyteidl/admin/agent.pb.validate.go +++ b/flyteidl/gen/pb-go/flyteidl/admin/agent.pb.validate.go @@ -378,6 +378,21 @@ func (m *GetTaskResponse) Validate() error { } } + for idx, item := range m.GetLogLinks() { + _, _ = idx, item + + if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GetTaskResponseValidationError{ + field: fmt.Sprintf("LogLinks[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + return nil } diff --git a/flyteidl/gen/pb-go/flyteidl/service/agent.swagger.json b/flyteidl/gen/pb-go/flyteidl/service/agent.swagger.json index e71c02d2de..78aa113053 100644 --- a/flyteidl/gen/pb-go/flyteidl/service/agent.swagger.json +++ b/flyteidl/gen/pb-go/flyteidl/service/agent.swagger.json @@ -163,6 +163,15 @@ } } }, + "TaskLogMessageFormat": { + "type": "string", + "enum": [ + "UNKNOWN", + "CSV", + "JSON" + ], + "default": "UNKNOWN" + }, "adminCreateTaskResponse": { "type": "object", "properties": { @@ -183,6 +192,13 @@ "properties": { "resource": { "$ref": "#/definitions/adminResource" + }, + "log_links": { + "type": "array", + "items": { + "$ref": "#/definitions/coreTaskLog" + }, + "description": "log information for the task execution." } }, "description": "Response to get an individual task resource." @@ -951,6 +967,24 @@ }, "description": "Encapsulation of fields that identify a Flyte task execution entity." }, + "coreTaskLog": { + "type": "object", + "properties": { + "uri": { + "type": "string" + }, + "name": { + "type": "string" + }, + "message_format": { + "$ref": "#/definitions/TaskLogMessageFormat" + }, + "ttl": { + "type": "string" + } + }, + "title": "Log information for the task that is specific to a log sink\nWhen our log story is flushed out, we may have more metadata here like log link expiry" + }, "coreTaskMetadata": { "type": "object", "properties": { diff --git a/flyteidl/gen/pb-java/flyteidl/admin/Agent.java b/flyteidl/gen/pb-java/flyteidl/admin/Agent.java index b2dfd16e61..b18c298749 100644 --- a/flyteidl/gen/pb-java/flyteidl/admin/Agent.java +++ b/flyteidl/gen/pb-java/flyteidl/admin/Agent.java @@ -4811,6 +4811,50 @@ public interface GetTaskResponseOrBuilder extends * .flyteidl.admin.Resource resource = 1; */ flyteidl.admin.Agent.ResourceOrBuilder getResourceOrBuilder(); + + /** + *
+     * log information for the task execution.
+     * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + java.util.List + getLogLinksList(); + /** + *
+     * log information for the task execution.
+     * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + flyteidl.core.Execution.TaskLog getLogLinks(int index); + /** + *
+     * log information for the task execution.
+     * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + int getLogLinksCount(); + /** + *
+     * log information for the task execution.
+     * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + java.util.List + getLogLinksOrBuilderList(); + /** + *
+     * log information for the task execution.
+     * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + flyteidl.core.Execution.TaskLogOrBuilder getLogLinksOrBuilder( + int index); } /** *
@@ -4829,6 +4873,7 @@ private GetTaskResponse(com.google.protobuf.GeneratedMessageV3.Builder builde
       super(builder);
     }
     private GetTaskResponse() {
+      logLinks_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
@@ -4868,6 +4913,15 @@ private GetTaskResponse(
 
               break;
             }
+            case 18: {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
+                logLinks_ = new java.util.ArrayList();
+                mutable_bitField0_ |= 0x00000002;
+              }
+              logLinks_.add(
+                  input.readMessage(flyteidl.core.Execution.TaskLog.parser(), extensionRegistry));
+              break;
+            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -4883,6 +4937,9 @@ private GetTaskResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
+          logLinks_ = java.util.Collections.unmodifiableList(logLinks_);
+        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
@@ -4900,6 +4957,7 @@ private GetTaskResponse(
               flyteidl.admin.Agent.GetTaskResponse.class, flyteidl.admin.Agent.GetTaskResponse.Builder.class);
     }
 
+    private int bitField0_;
     public static final int RESOURCE_FIELD_NUMBER = 1;
     private flyteidl.admin.Agent.Resource resource_;
     /**
@@ -4921,6 +4979,61 @@ public flyteidl.admin.Agent.ResourceOrBuilder getResourceOrBuilder() {
       return getResource();
     }
 
+    public static final int LOG_LINKS_FIELD_NUMBER = 2;
+    private java.util.List logLinks_;
+    /**
+     * 
+     * log information for the task execution.
+     * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public java.util.List getLogLinksList() { + return logLinks_; + } + /** + *
+     * log information for the task execution.
+     * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public java.util.List + getLogLinksOrBuilderList() { + return logLinks_; + } + /** + *
+     * log information for the task execution.
+     * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public int getLogLinksCount() { + return logLinks_.size(); + } + /** + *
+     * log information for the task execution.
+     * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public flyteidl.core.Execution.TaskLog getLogLinks(int index) { + return logLinks_.get(index); + } + /** + *
+     * log information for the task execution.
+     * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public flyteidl.core.Execution.TaskLogOrBuilder getLogLinksOrBuilder( + int index) { + return logLinks_.get(index); + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -4938,6 +5051,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (resource_ != null) { output.writeMessage(1, getResource()); } + for (int i = 0; i < logLinks_.size(); i++) { + output.writeMessage(2, logLinks_.get(i)); + } unknownFields.writeTo(output); } @@ -4951,6 +5067,10 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeMessageSize(1, getResource()); } + for (int i = 0; i < logLinks_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, logLinks_.get(i)); + } size += unknownFields.getSerializedSize(); memoizedSize = size; return size; @@ -4971,6 +5091,8 @@ public boolean equals(final java.lang.Object obj) { if (!getResource() .equals(other.getResource())) return false; } + if (!getLogLinksList() + .equals(other.getLogLinksList())) return false; if (!unknownFields.equals(other.unknownFields)) return false; return true; } @@ -4986,6 +5108,10 @@ public int hashCode() { hash = (37 * hash) + RESOURCE_FIELD_NUMBER; hash = (53 * hash) + getResource().hashCode(); } + if (getLogLinksCount() > 0) { + hash = (37 * hash) + LOG_LINKS_FIELD_NUMBER; + hash = (53 * hash) + getLogLinksList().hashCode(); + } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; @@ -5118,6 +5244,7 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { + getLogLinksFieldBuilder(); } } @java.lang.Override @@ -5129,6 +5256,12 @@ public Builder clear() { resource_ = null; resourceBuilder_ = null; } + if (logLinksBuilder_ == null) { + logLinks_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + } else { + logLinksBuilder_.clear(); + } return this; } @@ -5155,11 +5288,23 @@ public flyteidl.admin.Agent.GetTaskResponse build() { @java.lang.Override public flyteidl.admin.Agent.GetTaskResponse buildPartial() { flyteidl.admin.Agent.GetTaskResponse result = new flyteidl.admin.Agent.GetTaskResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; if (resourceBuilder_ == null) { result.resource_ = resource_; } else { result.resource_ = resourceBuilder_.build(); } + if (logLinksBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0)) { + logLinks_ = java.util.Collections.unmodifiableList(logLinks_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.logLinks_ = logLinks_; + } else { + result.logLinks_ = logLinksBuilder_.build(); + } + result.bitField0_ = to_bitField0_; onBuilt(); return result; } @@ -5211,6 +5356,32 @@ public Builder mergeFrom(flyteidl.admin.Agent.GetTaskResponse other) { if (other.hasResource()) { mergeResource(other.getResource()); } + if (logLinksBuilder_ == null) { + if (!other.logLinks_.isEmpty()) { + if (logLinks_.isEmpty()) { + logLinks_ = other.logLinks_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureLogLinksIsMutable(); + logLinks_.addAll(other.logLinks_); + } + onChanged(); + } + } else { + if (!other.logLinks_.isEmpty()) { + if (logLinksBuilder_.isEmpty()) { + logLinksBuilder_.dispose(); + logLinksBuilder_ = null; + logLinks_ = other.logLinks_; + bitField0_ = (bitField0_ & ~0x00000002); + logLinksBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getLogLinksFieldBuilder() : null; + } else { + logLinksBuilder_.addAllMessages(other.logLinks_); + } + } + } this.mergeUnknownFields(other.unknownFields); onChanged(); return this; @@ -5239,6 +5410,7 @@ public Builder mergeFrom( } return this; } + private int bitField0_; private flyteidl.admin.Agent.Resource resource_; private com.google.protobuf.SingleFieldBuilderV3< @@ -5356,6 +5528,318 @@ public flyteidl.admin.Agent.ResourceOrBuilder getResourceOrBuilder() { } return resourceBuilder_; } + + private java.util.List logLinks_ = + java.util.Collections.emptyList(); + private void ensureLogLinksIsMutable() { + if (!((bitField0_ & 0x00000002) != 0)) { + logLinks_ = new java.util.ArrayList(logLinks_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + flyteidl.core.Execution.TaskLog, flyteidl.core.Execution.TaskLog.Builder, flyteidl.core.Execution.TaskLogOrBuilder> logLinksBuilder_; + + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public java.util.List getLogLinksList() { + if (logLinksBuilder_ == null) { + return java.util.Collections.unmodifiableList(logLinks_); + } else { + return logLinksBuilder_.getMessageList(); + } + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public int getLogLinksCount() { + if (logLinksBuilder_ == null) { + return logLinks_.size(); + } else { + return logLinksBuilder_.getCount(); + } + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public flyteidl.core.Execution.TaskLog getLogLinks(int index) { + if (logLinksBuilder_ == null) { + return logLinks_.get(index); + } else { + return logLinksBuilder_.getMessage(index); + } + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public Builder setLogLinks( + int index, flyteidl.core.Execution.TaskLog value) { + if (logLinksBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLogLinksIsMutable(); + logLinks_.set(index, value); + onChanged(); + } else { + logLinksBuilder_.setMessage(index, value); + } + return this; + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public Builder setLogLinks( + int index, flyteidl.core.Execution.TaskLog.Builder builderForValue) { + if (logLinksBuilder_ == null) { + ensureLogLinksIsMutable(); + logLinks_.set(index, builderForValue.build()); + onChanged(); + } else { + logLinksBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public Builder addLogLinks(flyteidl.core.Execution.TaskLog value) { + if (logLinksBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLogLinksIsMutable(); + logLinks_.add(value); + onChanged(); + } else { + logLinksBuilder_.addMessage(value); + } + return this; + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public Builder addLogLinks( + int index, flyteidl.core.Execution.TaskLog value) { + if (logLinksBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLogLinksIsMutable(); + logLinks_.add(index, value); + onChanged(); + } else { + logLinksBuilder_.addMessage(index, value); + } + return this; + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public Builder addLogLinks( + flyteidl.core.Execution.TaskLog.Builder builderForValue) { + if (logLinksBuilder_ == null) { + ensureLogLinksIsMutable(); + logLinks_.add(builderForValue.build()); + onChanged(); + } else { + logLinksBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public Builder addLogLinks( + int index, flyteidl.core.Execution.TaskLog.Builder builderForValue) { + if (logLinksBuilder_ == null) { + ensureLogLinksIsMutable(); + logLinks_.add(index, builderForValue.build()); + onChanged(); + } else { + logLinksBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public Builder addAllLogLinks( + java.lang.Iterable values) { + if (logLinksBuilder_ == null) { + ensureLogLinksIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, logLinks_); + onChanged(); + } else { + logLinksBuilder_.addAllMessages(values); + } + return this; + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public Builder clearLogLinks() { + if (logLinksBuilder_ == null) { + logLinks_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + logLinksBuilder_.clear(); + } + return this; + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public Builder removeLogLinks(int index) { + if (logLinksBuilder_ == null) { + ensureLogLinksIsMutable(); + logLinks_.remove(index); + onChanged(); + } else { + logLinksBuilder_.remove(index); + } + return this; + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public flyteidl.core.Execution.TaskLog.Builder getLogLinksBuilder( + int index) { + return getLogLinksFieldBuilder().getBuilder(index); + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public flyteidl.core.Execution.TaskLogOrBuilder getLogLinksOrBuilder( + int index) { + if (logLinksBuilder_ == null) { + return logLinks_.get(index); } else { + return logLinksBuilder_.getMessageOrBuilder(index); + } + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public java.util.List + getLogLinksOrBuilderList() { + if (logLinksBuilder_ != null) { + return logLinksBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(logLinks_); + } + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public flyteidl.core.Execution.TaskLog.Builder addLogLinksBuilder() { + return getLogLinksFieldBuilder().addBuilder( + flyteidl.core.Execution.TaskLog.getDefaultInstance()); + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public flyteidl.core.Execution.TaskLog.Builder addLogLinksBuilder( + int index) { + return getLogLinksFieldBuilder().addBuilder( + index, flyteidl.core.Execution.TaskLog.getDefaultInstance()); + } + /** + *
+       * log information for the task execution.
+       * 
+ * + * repeated .flyteidl.core.TaskLog log_links = 2; + */ + public java.util.List + getLogLinksBuilderList() { + return getLogLinksFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + flyteidl.core.Execution.TaskLog, flyteidl.core.Execution.TaskLog.Builder, flyteidl.core.Execution.TaskLogOrBuilder> + getLogLinksFieldBuilder() { + if (logLinksBuilder_ == null) { + logLinksBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + flyteidl.core.Execution.TaskLog, flyteidl.core.Execution.TaskLog.Builder, flyteidl.core.Execution.TaskLogOrBuilder>( + logLinks_, + ((bitField0_ & 0x00000002) != 0), + getParentForChildren(), + isClean()); + logLinks_ = null; + } + return logLinksBuilder_; + } @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { @@ -7574,39 +8058,40 @@ public flyteidl.admin.Agent.DeleteTaskResponse getDefaultInstanceForType() { "dmin\032\034flyteidl/core/literals.proto\032\031flyt" + "eidl/core/tasks.proto\032\035flyteidl/core/int" + "erface.proto\032\036flyteidl/core/identifier.p" + - "roto\"\232\004\n\025TaskExecutionMetadata\022A\n\021task_e" + - "xecution_id\030\001 \001(\0132&.flyteidl.core.TaskEx" + - "ecutionIdentifier\022\021\n\tnamespace\030\002 \001(\t\022A\n\006" + - "labels\030\003 \003(\01321.flyteidl.admin.TaskExecut" + - "ionMetadata.LabelsEntry\022K\n\013annotations\030\004" + - " \003(\01326.flyteidl.admin.TaskExecutionMetad" + - "ata.AnnotationsEntry\022\033\n\023k8s_service_acco" + - "unt\030\005 \001(\t\022^\n\025environment_variables\030\006 \003(\013" + - "2?.flyteidl.admin.TaskExecutionMetadata." + - "EnvironmentVariablesEntry\032-\n\013LabelsEntry" + - "\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\0322\n\020Anno" + - "tationsEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t" + - ":\0028\001\032;\n\031EnvironmentVariablesEntry\022\013\n\003key" + - "\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"\314\001\n\021CreateTask" + - "Request\022)\n\006inputs\030\001 \001(\0132\031.flyteidl.core." + - "LiteralMap\022-\n\010template\030\002 \001(\0132\033.flyteidl." + - "core.TaskTemplate\022\025\n\routput_prefix\030\003 \001(\t" + - "\022F\n\027task_execution_metadata\030\004 \001(\0132%.flyt" + - "eidl.admin.TaskExecutionMetadata\"+\n\022Crea" + - "teTaskResponse\022\025\n\rresource_meta\030\001 \001(\014\":\n" + - "\016GetTaskRequest\022\021\n\ttask_type\030\001 \001(\t\022\025\n\rre" + - "source_meta\030\002 \001(\014\"=\n\017GetTaskResponse\022*\n\010" + - "resource\030\001 \001(\0132\030.flyteidl.admin.Resource" + - "\"m\n\010Resource\022$\n\005state\030\001 \001(\0162\025.flyteidl.a" + - "dmin.State\022*\n\007outputs\030\002 \001(\0132\031.flyteidl.c" + - "ore.LiteralMap\022\017\n\007message\030\003 \001(\t\"=\n\021Delet" + - "eTaskRequest\022\021\n\ttask_type\030\001 \001(\t\022\025\n\rresou" + - "rce_meta\030\002 \001(\014\"\024\n\022DeleteTaskResponse*^\n\005" + - "State\022\025\n\021RETRYABLE_FAILURE\020\000\022\025\n\021PERMANEN" + - "T_FAILURE\020\001\022\013\n\007PENDING\020\002\022\013\n\007RUNNING\020\003\022\r\n" + - "\tSUCCEEDED\020\004B=Z;github.com/flyteorg/flyt" + - "e/flyteidl/gen/pb-go/flyteidl/adminb\006pro" + - "to3" + "roto\032\035flyteidl/core/execution.proto\"\232\004\n\025" + + "TaskExecutionMetadata\022A\n\021task_execution_" + + "id\030\001 \001(\0132&.flyteidl.core.TaskExecutionId" + + "entifier\022\021\n\tnamespace\030\002 \001(\t\022A\n\006labels\030\003 " + + "\003(\01321.flyteidl.admin.TaskExecutionMetada" + + "ta.LabelsEntry\022K\n\013annotations\030\004 \003(\01326.fl" + + "yteidl.admin.TaskExecutionMetadata.Annot" + + "ationsEntry\022\033\n\023k8s_service_account\030\005 \001(\t" + + "\022^\n\025environment_variables\030\006 \003(\0132?.flytei" + + "dl.admin.TaskExecutionMetadata.Environme" + + "ntVariablesEntry\032-\n\013LabelsEntry\022\013\n\003key\030\001" + + " \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\0322\n\020AnnotationsEn" + + "try\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\032;\n\031E" + + "nvironmentVariablesEntry\022\013\n\003key\030\001 \001(\t\022\r\n" + + "\005value\030\002 \001(\t:\0028\001\"\314\001\n\021CreateTaskRequest\022)" + + "\n\006inputs\030\001 \001(\0132\031.flyteidl.core.LiteralMa" + + "p\022-\n\010template\030\002 \001(\0132\033.flyteidl.core.Task" + + "Template\022\025\n\routput_prefix\030\003 \001(\t\022F\n\027task_" + + "execution_metadata\030\004 \001(\0132%.flyteidl.admi" + + "n.TaskExecutionMetadata\"+\n\022CreateTaskRes" + + "ponse\022\025\n\rresource_meta\030\001 \001(\014\":\n\016GetTaskR" + + "equest\022\021\n\ttask_type\030\001 \001(\t\022\025\n\rresource_me" + + "ta\030\002 \001(\014\"h\n\017GetTaskResponse\022*\n\010resource\030" + + "\001 \001(\0132\030.flyteidl.admin.Resource\022)\n\tlog_l" + + "inks\030\002 \003(\0132\026.flyteidl.core.TaskLog\"m\n\010Re" + + "source\022$\n\005state\030\001 \001(\0162\025.flyteidl.admin.S" + + "tate\022*\n\007outputs\030\002 \001(\0132\031.flyteidl.core.Li" + + "teralMap\022\017\n\007message\030\003 \001(\t\"=\n\021DeleteTaskR" + + "equest\022\021\n\ttask_type\030\001 \001(\t\022\025\n\rresource_me" + + "ta\030\002 \001(\014\"\024\n\022DeleteTaskResponse*^\n\005State\022" + + "\025\n\021RETRYABLE_FAILURE\020\000\022\025\n\021PERMANENT_FAIL" + + "URE\020\001\022\013\n\007PENDING\020\002\022\013\n\007RUNNING\020\003\022\r\n\tSUCCE" + + "EDED\020\004B=Z;github.com/flyteorg/flyte/flyt" + + "eidl/gen/pb-go/flyteidl/adminb\006proto3" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { @@ -7623,6 +8108,7 @@ public com.google.protobuf.ExtensionRegistry assignDescriptors( flyteidl.core.Tasks.getDescriptor(), flyteidl.core.Interface.getDescriptor(), flyteidl.core.IdentifierOuterClass.getDescriptor(), + flyteidl.core.Execution.getDescriptor(), }, assigner); internal_static_flyteidl_admin_TaskExecutionMetadata_descriptor = getDescriptor().getMessageTypes().get(0); @@ -7671,7 +8157,7 @@ public com.google.protobuf.ExtensionRegistry assignDescriptors( internal_static_flyteidl_admin_GetTaskResponse_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_flyteidl_admin_GetTaskResponse_descriptor, - new java.lang.String[] { "Resource", }); + new java.lang.String[] { "Resource", "LogLinks", }); internal_static_flyteidl_admin_Resource_descriptor = getDescriptor().getMessageTypes().get(5); internal_static_flyteidl_admin_Resource_fieldAccessorTable = new @@ -7694,6 +8180,7 @@ public com.google.protobuf.ExtensionRegistry assignDescriptors( flyteidl.core.Tasks.getDescriptor(); flyteidl.core.Interface.getDescriptor(); flyteidl.core.IdentifierOuterClass.getDescriptor(); + flyteidl.core.Execution.getDescriptor(); } // @@protoc_insertion_point(outer_class_scope) diff --git a/flyteidl/gen/pb-js/flyteidl.d.ts b/flyteidl/gen/pb-js/flyteidl.d.ts index f7186dea01..20a01db909 100644 --- a/flyteidl/gen/pb-js/flyteidl.d.ts +++ b/flyteidl/gen/pb-js/flyteidl.d.ts @@ -8132,6 +8132,9 @@ export namespace flyteidl { /** GetTaskResponse resource */ resource?: (flyteidl.admin.IResource|null); + + /** GetTaskResponse logLinks */ + logLinks?: (flyteidl.core.ITaskLog[]|null); } /** Represents a GetTaskResponse. */ @@ -8146,6 +8149,9 @@ export namespace flyteidl { /** GetTaskResponse resource. */ public resource?: (flyteidl.admin.IResource|null); + /** GetTaskResponse logLinks. */ + public logLinks: flyteidl.core.ITaskLog[]; + /** * Creates a new GetTaskResponse instance using the specified properties. * @param [properties] Properties to set diff --git a/flyteidl/gen/pb-js/flyteidl.js b/flyteidl/gen/pb-js/flyteidl.js index 223d617ecf..d9983504cc 100644 --- a/flyteidl/gen/pb-js/flyteidl.js +++ b/flyteidl/gen/pb-js/flyteidl.js @@ -19875,6 +19875,7 @@ * @memberof flyteidl.admin * @interface IGetTaskResponse * @property {flyteidl.admin.IResource|null} [resource] GetTaskResponse resource + * @property {Array.|null} [logLinks] GetTaskResponse logLinks */ /** @@ -19886,6 +19887,7 @@ * @param {flyteidl.admin.IGetTaskResponse=} [properties] Properties to set */ function GetTaskResponse(properties) { + this.logLinks = []; if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -19900,6 +19902,14 @@ */ GetTaskResponse.prototype.resource = null; + /** + * GetTaskResponse logLinks. + * @member {Array.} logLinks + * @memberof flyteidl.admin.GetTaskResponse + * @instance + */ + GetTaskResponse.prototype.logLinks = $util.emptyArray; + /** * Creates a new GetTaskResponse instance using the specified properties. * @function create @@ -19926,6 +19936,9 @@ writer = $Writer.create(); if (message.resource != null && message.hasOwnProperty("resource")) $root.flyteidl.admin.Resource.encode(message.resource, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.logLinks != null && message.logLinks.length) + for (var i = 0; i < message.logLinks.length; ++i) + $root.flyteidl.core.TaskLog.encode(message.logLinks[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); return writer; }; @@ -19950,6 +19963,11 @@ case 1: message.resource = $root.flyteidl.admin.Resource.decode(reader, reader.uint32()); break; + case 2: + if (!(message.logLinks && message.logLinks.length)) + message.logLinks = []; + message.logLinks.push($root.flyteidl.core.TaskLog.decode(reader, reader.uint32())); + break; default: reader.skipType(tag & 7); break; @@ -19974,6 +19992,15 @@ if (error) return "resource." + error; } + if (message.logLinks != null && message.hasOwnProperty("logLinks")) { + if (!Array.isArray(message.logLinks)) + return "logLinks: array expected"; + for (var i = 0; i < message.logLinks.length; ++i) { + var error = $root.flyteidl.core.TaskLog.verify(message.logLinks[i]); + if (error) + return "logLinks." + error; + } + } return null; }; diff --git a/flyteidl/gen/pb_python/flyteidl/admin/agent_pb2.py b/flyteidl/gen/pb_python/flyteidl/admin/agent_pb2.py index bb0aa9384a..c16839946c 100644 --- a/flyteidl/gen/pb_python/flyteidl/admin/agent_pb2.py +++ b/flyteidl/gen/pb_python/flyteidl/admin/agent_pb2.py @@ -15,9 +15,10 @@ from flyteidl.core import tasks_pb2 as flyteidl_dot_core_dot_tasks__pb2 from flyteidl.core import interface_pb2 as flyteidl_dot_core_dot_interface__pb2 from flyteidl.core import identifier_pb2 as flyteidl_dot_core_dot_identifier__pb2 +from flyteidl.core import execution_pb2 as flyteidl_dot_core_dot_execution__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1a\x66lyteidl/admin/agent.proto\x12\x0e\x66lyteidl.admin\x1a\x1c\x66lyteidl/core/literals.proto\x1a\x19\x66lyteidl/core/tasks.proto\x1a\x1d\x66lyteidl/core/interface.proto\x1a\x1e\x66lyteidl/core/identifier.proto\"\x98\x05\n\x15TaskExecutionMetadata\x12R\n\x11task_execution_id\x18\x01 \x01(\x0b\x32&.flyteidl.core.TaskExecutionIdentifierR\x0ftaskExecutionId\x12\x1c\n\tnamespace\x18\x02 \x01(\tR\tnamespace\x12I\n\x06labels\x18\x03 \x03(\x0b\x32\x31.flyteidl.admin.TaskExecutionMetadata.LabelsEntryR\x06labels\x12X\n\x0b\x61nnotations\x18\x04 \x03(\x0b\x32\x36.flyteidl.admin.TaskExecutionMetadata.AnnotationsEntryR\x0b\x61nnotations\x12.\n\x13k8s_service_account\x18\x05 \x01(\tR\x11k8sServiceAccount\x12t\n\x15\x65nvironment_variables\x18\x06 \x03(\x0b\x32?.flyteidl.admin.TaskExecutionMetadata.EnvironmentVariablesEntryR\x14\x65nvironmentVariables\x1a\x39\n\x0bLabelsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x1a>\n\x10\x41nnotationsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x1aG\n\x19\x45nvironmentVariablesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\x83\x02\n\x11\x43reateTaskRequest\x12\x31\n\x06inputs\x18\x01 \x01(\x0b\x32\x19.flyteidl.core.LiteralMapR\x06inputs\x12\x37\n\x08template\x18\x02 \x01(\x0b\x32\x1b.flyteidl.core.TaskTemplateR\x08template\x12#\n\routput_prefix\x18\x03 \x01(\tR\x0coutputPrefix\x12]\n\x17task_execution_metadata\x18\x04 \x01(\x0b\x32%.flyteidl.admin.TaskExecutionMetadataR\x15taskExecutionMetadata\"9\n\x12\x43reateTaskResponse\x12#\n\rresource_meta\x18\x01 \x01(\x0cR\x0cresourceMeta\"R\n\x0eGetTaskRequest\x12\x1b\n\ttask_type\x18\x01 \x01(\tR\x08taskType\x12#\n\rresource_meta\x18\x02 \x01(\x0cR\x0cresourceMeta\"G\n\x0fGetTaskResponse\x12\x34\n\x08resource\x18\x01 \x01(\x0b\x32\x18.flyteidl.admin.ResourceR\x08resource\"\x86\x01\n\x08Resource\x12+\n\x05state\x18\x01 \x01(\x0e\x32\x15.flyteidl.admin.StateR\x05state\x12\x33\n\x07outputs\x18\x02 \x01(\x0b\x32\x19.flyteidl.core.LiteralMapR\x07outputs\x12\x18\n\x07message\x18\x03 \x01(\tR\x07message\"U\n\x11\x44\x65leteTaskRequest\x12\x1b\n\ttask_type\x18\x01 \x01(\tR\x08taskType\x12#\n\rresource_meta\x18\x02 \x01(\x0cR\x0cresourceMeta\"\x14\n\x12\x44\x65leteTaskResponse*^\n\x05State\x12\x15\n\x11RETRYABLE_FAILURE\x10\x00\x12\x15\n\x11PERMANENT_FAILURE\x10\x01\x12\x0b\n\x07PENDING\x10\x02\x12\x0b\n\x07RUNNING\x10\x03\x12\r\n\tSUCCEEDED\x10\x04\x42\xb6\x01\n\x12\x63om.flyteidl.adminB\nAgentProtoP\x01Z;github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/admin\xa2\x02\x03\x46\x41X\xaa\x02\x0e\x46lyteidl.Admin\xca\x02\x0e\x46lyteidl\\Admin\xe2\x02\x1a\x46lyteidl\\Admin\\GPBMetadata\xea\x02\x0f\x46lyteidl::Adminb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1a\x66lyteidl/admin/agent.proto\x12\x0e\x66lyteidl.admin\x1a\x1c\x66lyteidl/core/literals.proto\x1a\x19\x66lyteidl/core/tasks.proto\x1a\x1d\x66lyteidl/core/interface.proto\x1a\x1e\x66lyteidl/core/identifier.proto\x1a\x1d\x66lyteidl/core/execution.proto\"\x98\x05\n\x15TaskExecutionMetadata\x12R\n\x11task_execution_id\x18\x01 \x01(\x0b\x32&.flyteidl.core.TaskExecutionIdentifierR\x0ftaskExecutionId\x12\x1c\n\tnamespace\x18\x02 \x01(\tR\tnamespace\x12I\n\x06labels\x18\x03 \x03(\x0b\x32\x31.flyteidl.admin.TaskExecutionMetadata.LabelsEntryR\x06labels\x12X\n\x0b\x61nnotations\x18\x04 \x03(\x0b\x32\x36.flyteidl.admin.TaskExecutionMetadata.AnnotationsEntryR\x0b\x61nnotations\x12.\n\x13k8s_service_account\x18\x05 \x01(\tR\x11k8sServiceAccount\x12t\n\x15\x65nvironment_variables\x18\x06 \x03(\x0b\x32?.flyteidl.admin.TaskExecutionMetadata.EnvironmentVariablesEntryR\x14\x65nvironmentVariables\x1a\x39\n\x0bLabelsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x1a>\n\x10\x41nnotationsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x1aG\n\x19\x45nvironmentVariablesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\x83\x02\n\x11\x43reateTaskRequest\x12\x31\n\x06inputs\x18\x01 \x01(\x0b\x32\x19.flyteidl.core.LiteralMapR\x06inputs\x12\x37\n\x08template\x18\x02 \x01(\x0b\x32\x1b.flyteidl.core.TaskTemplateR\x08template\x12#\n\routput_prefix\x18\x03 \x01(\tR\x0coutputPrefix\x12]\n\x17task_execution_metadata\x18\x04 \x01(\x0b\x32%.flyteidl.admin.TaskExecutionMetadataR\x15taskExecutionMetadata\"9\n\x12\x43reateTaskResponse\x12#\n\rresource_meta\x18\x01 \x01(\x0cR\x0cresourceMeta\"R\n\x0eGetTaskRequest\x12\x1b\n\ttask_type\x18\x01 \x01(\tR\x08taskType\x12#\n\rresource_meta\x18\x02 \x01(\x0cR\x0cresourceMeta\"|\n\x0fGetTaskResponse\x12\x34\n\x08resource\x18\x01 \x01(\x0b\x32\x18.flyteidl.admin.ResourceR\x08resource\x12\x33\n\tlog_links\x18\x02 \x03(\x0b\x32\x16.flyteidl.core.TaskLogR\x08logLinks\"\x86\x01\n\x08Resource\x12+\n\x05state\x18\x01 \x01(\x0e\x32\x15.flyteidl.admin.StateR\x05state\x12\x33\n\x07outputs\x18\x02 \x01(\x0b\x32\x19.flyteidl.core.LiteralMapR\x07outputs\x12\x18\n\x07message\x18\x03 \x01(\tR\x07message\"U\n\x11\x44\x65leteTaskRequest\x12\x1b\n\ttask_type\x18\x01 \x01(\tR\x08taskType\x12#\n\rresource_meta\x18\x02 \x01(\x0cR\x0cresourceMeta\"\x14\n\x12\x44\x65leteTaskResponse*^\n\x05State\x12\x15\n\x11RETRYABLE_FAILURE\x10\x00\x12\x15\n\x11PERMANENT_FAILURE\x10\x01\x12\x0b\n\x07PENDING\x10\x02\x12\x0b\n\x07RUNNING\x10\x03\x12\r\n\tSUCCEEDED\x10\x04\x42\xb6\x01\n\x12\x63om.flyteidl.adminB\nAgentProtoP\x01Z;github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/admin\xa2\x02\x03\x46\x41X\xaa\x02\x0e\x46lyteidl.Admin\xca\x02\x0e\x46lyteidl\\Admin\xe2\x02\x1a\x46lyteidl\\Admin\\GPBMetadata\xea\x02\x0f\x46lyteidl::Adminb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -32,28 +33,28 @@ _TASKEXECUTIONMETADATA_ANNOTATIONSENTRY._serialized_options = b'8\001' _TASKEXECUTIONMETADATA_ENVIRONMENTVARIABLESENTRY._options = None _TASKEXECUTIONMETADATA_ENVIRONMENTVARIABLESENTRY._serialized_options = b'8\001' - _globals['_STATE']._serialized_start=1557 - _globals['_STATE']._serialized_end=1651 - _globals['_TASKEXECUTIONMETADATA']._serialized_start=167 - _globals['_TASKEXECUTIONMETADATA']._serialized_end=831 - _globals['_TASKEXECUTIONMETADATA_LABELSENTRY']._serialized_start=637 - _globals['_TASKEXECUTIONMETADATA_LABELSENTRY']._serialized_end=694 - _globals['_TASKEXECUTIONMETADATA_ANNOTATIONSENTRY']._serialized_start=696 - _globals['_TASKEXECUTIONMETADATA_ANNOTATIONSENTRY']._serialized_end=758 - _globals['_TASKEXECUTIONMETADATA_ENVIRONMENTVARIABLESENTRY']._serialized_start=760 - _globals['_TASKEXECUTIONMETADATA_ENVIRONMENTVARIABLESENTRY']._serialized_end=831 - _globals['_CREATETASKREQUEST']._serialized_start=834 - _globals['_CREATETASKREQUEST']._serialized_end=1093 - _globals['_CREATETASKRESPONSE']._serialized_start=1095 - _globals['_CREATETASKRESPONSE']._serialized_end=1152 - _globals['_GETTASKREQUEST']._serialized_start=1154 - _globals['_GETTASKREQUEST']._serialized_end=1236 - _globals['_GETTASKRESPONSE']._serialized_start=1238 - _globals['_GETTASKRESPONSE']._serialized_end=1309 - _globals['_RESOURCE']._serialized_start=1312 - _globals['_RESOURCE']._serialized_end=1446 - _globals['_DELETETASKREQUEST']._serialized_start=1448 - _globals['_DELETETASKREQUEST']._serialized_end=1533 - _globals['_DELETETASKRESPONSE']._serialized_start=1535 - _globals['_DELETETASKRESPONSE']._serialized_end=1555 + _globals['_STATE']._serialized_start=1641 + _globals['_STATE']._serialized_end=1735 + _globals['_TASKEXECUTIONMETADATA']._serialized_start=198 + _globals['_TASKEXECUTIONMETADATA']._serialized_end=862 + _globals['_TASKEXECUTIONMETADATA_LABELSENTRY']._serialized_start=668 + _globals['_TASKEXECUTIONMETADATA_LABELSENTRY']._serialized_end=725 + _globals['_TASKEXECUTIONMETADATA_ANNOTATIONSENTRY']._serialized_start=727 + _globals['_TASKEXECUTIONMETADATA_ANNOTATIONSENTRY']._serialized_end=789 + _globals['_TASKEXECUTIONMETADATA_ENVIRONMENTVARIABLESENTRY']._serialized_start=791 + _globals['_TASKEXECUTIONMETADATA_ENVIRONMENTVARIABLESENTRY']._serialized_end=862 + _globals['_CREATETASKREQUEST']._serialized_start=865 + _globals['_CREATETASKREQUEST']._serialized_end=1124 + _globals['_CREATETASKRESPONSE']._serialized_start=1126 + _globals['_CREATETASKRESPONSE']._serialized_end=1183 + _globals['_GETTASKREQUEST']._serialized_start=1185 + _globals['_GETTASKREQUEST']._serialized_end=1267 + _globals['_GETTASKRESPONSE']._serialized_start=1269 + _globals['_GETTASKRESPONSE']._serialized_end=1393 + _globals['_RESOURCE']._serialized_start=1396 + _globals['_RESOURCE']._serialized_end=1530 + _globals['_DELETETASKREQUEST']._serialized_start=1532 + _globals['_DELETETASKREQUEST']._serialized_end=1617 + _globals['_DELETETASKRESPONSE']._serialized_start=1619 + _globals['_DELETETASKRESPONSE']._serialized_end=1639 # @@protoc_insertion_point(module_scope) diff --git a/flyteidl/gen/pb_python/flyteidl/admin/agent_pb2.pyi b/flyteidl/gen/pb_python/flyteidl/admin/agent_pb2.pyi index 6ca7ba23a7..0fd64d8e10 100644 --- a/flyteidl/gen/pb_python/flyteidl/admin/agent_pb2.pyi +++ b/flyteidl/gen/pb_python/flyteidl/admin/agent_pb2.pyi @@ -2,11 +2,12 @@ from flyteidl.core import literals_pb2 as _literals_pb2 from flyteidl.core import tasks_pb2 as _tasks_pb2 from flyteidl.core import interface_pb2 as _interface_pb2 from flyteidl.core import identifier_pb2 as _identifier_pb2 +from flyteidl.core import execution_pb2 as _execution_pb2 from google.protobuf.internal import containers as _containers from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message -from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union +from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union DESCRIPTOR: _descriptor.FileDescriptor @@ -87,10 +88,12 @@ class GetTaskRequest(_message.Message): def __init__(self, task_type: _Optional[str] = ..., resource_meta: _Optional[bytes] = ...) -> None: ... class GetTaskResponse(_message.Message): - __slots__ = ["resource"] + __slots__ = ["resource", "log_links"] RESOURCE_FIELD_NUMBER: _ClassVar[int] + LOG_LINKS_FIELD_NUMBER: _ClassVar[int] resource: Resource - def __init__(self, resource: _Optional[_Union[Resource, _Mapping]] = ...) -> None: ... + log_links: _containers.RepeatedCompositeFieldContainer[_execution_pb2.TaskLog] + def __init__(self, resource: _Optional[_Union[Resource, _Mapping]] = ..., log_links: _Optional[_Iterable[_Union[_execution_pb2.TaskLog, _Mapping]]] = ...) -> None: ... class Resource(_message.Message): __slots__ = ["state", "outputs", "message"] diff --git a/flyteidl/gen/pb_rust/flyteidl.admin.rs b/flyteidl/gen/pb_rust/flyteidl.admin.rs index 759983a507..66e07b56b1 100644 --- a/flyteidl/gen/pb_rust/flyteidl.admin.rs +++ b/flyteidl/gen/pb_rust/flyteidl.admin.rs @@ -66,6 +66,9 @@ pub struct GetTaskRequest { pub struct GetTaskResponse { #[prost(message, optional, tag="1")] pub resource: ::core::option::Option, + /// log information for the task execution. + #[prost(message, repeated, tag="2")] + pub log_links: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/flyteidl/protos/flyteidl/admin/agent.proto b/flyteidl/protos/flyteidl/admin/agent.proto index a4dade0953..a3d1a5a4dd 100644 --- a/flyteidl/protos/flyteidl/admin/agent.proto +++ b/flyteidl/protos/flyteidl/admin/agent.proto @@ -7,6 +7,7 @@ import "flyteidl/core/literals.proto"; import "flyteidl/core/tasks.proto"; import "flyteidl/core/interface.proto"; import "flyteidl/core/identifier.proto"; +import "flyteidl/core/execution.proto"; // The state of the execution is used to control its visibility in the UI/CLI. enum State { @@ -64,6 +65,8 @@ message GetTaskRequest { // Response to get an individual task resource. message GetTaskResponse { Resource resource = 1; + // log information for the task execution. + repeated core.TaskLog log_links = 2; } message Resource { diff --git a/flyteplugins/go/tasks/plugins/webapi/agent/plugin.go b/flyteplugins/go/tasks/plugins/webapi/agent/plugin.go index d115bad896..2b3d8dbba9 100644 --- a/flyteplugins/go/tasks/plugins/webapi/agent/plugin.go +++ b/flyteplugins/go/tasks/plugins/webapi/agent/plugin.go @@ -37,9 +37,10 @@ type Plugin struct { } type ResourceWrapper struct { - State admin.State - Outputs *flyteIdl.LiteralMap - Message string + State admin.State + Outputs *flyteIdl.LiteralMap + Message string + LogLinks []*flyteIdl.TaskLog } type ResourceMetaWrapper struct { @@ -140,9 +141,10 @@ func (p Plugin) Get(ctx context.Context, taskCtx webapi.GetContext) (latest weba } return ResourceWrapper{ - State: res.Resource.State, - Outputs: res.Resource.Outputs, - Message: res.Resource.Message, + State: res.Resource.State, + Outputs: res.Resource.Outputs, + Message: res.Resource.Message, + LogLinks: res.LogLinks, }, nil } @@ -170,7 +172,7 @@ func (p Plugin) Delete(ctx context.Context, taskCtx webapi.DeleteContext) error func (p Plugin) Status(ctx context.Context, taskCtx webapi.StatusContext) (phase core.PhaseInfo, err error) { resource := taskCtx.Resource().(ResourceWrapper) - taskInfo := &core.TaskInfo{} + taskInfo := &core.TaskInfo{Logs: resource.LogLinks} switch resource.State { case admin.State_PENDING: diff --git a/flyteplugins/go/tasks/plugins/webapi/agent/plugin_test.go b/flyteplugins/go/tasks/plugins/webapi/agent/plugin_test.go index ee3b699e9d..b1fdd61e79 100644 --- a/flyteplugins/go/tasks/plugins/webapi/agent/plugin_test.go +++ b/flyteplugins/go/tasks/plugins/webapi/agent/plugin_test.go @@ -2,6 +2,7 @@ package agent import ( "context" + flyteidlcore "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core" "testing" "time" @@ -104,9 +105,10 @@ func TestPlugin(t *testing.T) { t.Run("test PENDING Status", func(t *testing.T) { taskContext := new(webapiPlugin.StatusContext) taskContext.On("Resource").Return(ResourceWrapper{ - State: admin.State_PENDING, - Outputs: nil, - Message: "Waiting for cluster", + State: admin.State_PENDING, + Outputs: nil, + Message: "Waiting for cluster", + LogLinks: []*flyteidlcore.TaskLog{{Uri: "http://localhost:3000/log", Name: "Log Link"}}, }) phase, err := plugin.Status(context.Background(), taskContext) @@ -118,9 +120,10 @@ func TestPlugin(t *testing.T) { t.Run("test RUNNING Status", func(t *testing.T) { taskContext := new(webapiPlugin.StatusContext) taskContext.On("Resource").Return(ResourceWrapper{ - State: admin.State_RUNNING, - Outputs: nil, - Message: "Job is running", + State: admin.State_RUNNING, + Outputs: nil, + Message: "Job is running", + LogLinks: []*flyteidlcore.TaskLog{{Uri: "http://localhost:3000/log", Name: "Log Link"}}, }) phase, err := plugin.Status(context.Background(), taskContext) @@ -131,9 +134,10 @@ func TestPlugin(t *testing.T) { t.Run("test PERMANENT_FAILURE Status", func(t *testing.T) { taskContext := new(webapiPlugin.StatusContext) taskContext.On("Resource").Return(ResourceWrapper{ - State: admin.State_PERMANENT_FAILURE, - Outputs: nil, - Message: "", + State: admin.State_PERMANENT_FAILURE, + Outputs: nil, + Message: "", + LogLinks: []*flyteidlcore.TaskLog{{Uri: "http://localhost:3000/log", Name: "Log Link"}}, }) phase, err := plugin.Status(context.Background(), taskContext) @@ -144,9 +148,10 @@ func TestPlugin(t *testing.T) { t.Run("test RETRYABLE_FAILURE Status", func(t *testing.T) { taskContext := new(webapiPlugin.StatusContext) taskContext.On("Resource").Return(ResourceWrapper{ - State: admin.State_RETRYABLE_FAILURE, - Outputs: nil, - Message: "", + State: admin.State_RETRYABLE_FAILURE, + Outputs: nil, + Message: "", + LogLinks: []*flyteidlcore.TaskLog{{Uri: "http://localhost:3000/log", Name: "Log Link"}}, }) phase, err := plugin.Status(context.Background(), taskContext) @@ -157,9 +162,10 @@ func TestPlugin(t *testing.T) { t.Run("test UNDEFINED Status", func(t *testing.T) { taskContext := new(webapiPlugin.StatusContext) taskContext.On("Resource").Return(ResourceWrapper{ - State: 5, - Outputs: nil, - Message: "", + State: 5, + Outputs: nil, + Message: "", + LogLinks: []*flyteidlcore.TaskLog{{Uri: "http://localhost:3000/log", Name: "Log Link"}}, }) phase, err := plugin.Status(context.Background(), taskContext) From 350bb2b0b561e7221c78d26526f158d2e92421b3 Mon Sep 17 00:00:00 2001 From: Nikki Everett Date: Tue, 5 Dec 2023 15:13:45 -0600 Subject: [PATCH 06/19] remove broken link (#4518) Signed-off-by: nikki everett Co-authored-by: Eduardo Apolinario <653394+eapolinario@users.noreply.github.com> --- rsts/concepts/data_management.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rsts/concepts/data_management.rst b/rsts/concepts/data_management.rst index 33a7f499a1..0d4edbd0a8 100644 --- a/rsts/concepts/data_management.rst +++ b/rsts/concepts/data_management.rst @@ -168,7 +168,7 @@ Between Tasks Bringing in Your Own Datastores for Raw Data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Flytekit has a pluggable `data persistence layer `__. +Flytekit has a pluggable data persistence layer. This is driven by PROTOCOL. For example, it is theoretically possible to use S3 ``s3://`` for metadata and GCS ``gcs://`` for raw data. It is also possible to create your own protocol ``my_fs://``, to change how data is stored and accessed. But for Metadata, the data should be accessible to Flyte control plane. From c049865cba017ad826405c7145cd3eccbc553232 Mon Sep 17 00:00:00 2001 From: Flyte Bot Date: Tue, 5 Dec 2023 16:16:09 -0800 Subject: [PATCH 07/19] Update Flyte components (#4525) * Update Flyte Components Signed-off-by: Flyte-Bot * Add CHANGELOG-v1.10.6.md and bump version in rsts/conf.py Signed-off-by: Eduardo Apolinario * Fix typo Signed-off-by: Eduardo Apolinario * Avoid rate-limiting in gh workflows by using authenticated requests Signed-off-by: Eduardo Apolinario --------- Signed-off-by: Flyte-Bot Signed-off-by: Eduardo Apolinario Co-authored-by: eapolinario Co-authored-by: Eduardo Apolinario <653394+eapolinario@users.noreply.github.com> --- .github/workflows/checks.yml | 2 + .github/workflows/go_generate.yml | 5 + CHANGELOG/CHANGELOG-v1.10.6.md | 157 ++++++++++++++++++ charts/flyte-binary/README.md | 2 +- charts/flyte-binary/values.yaml | 2 +- charts/flyte-core/README.md | 12 +- charts/flyte-core/values.yaml | 10 +- charts/flyte/README.md | 16 +- charts/flyte/values.yaml | 10 +- .../flyte_aws_scheduler_helm_generated.yaml | 30 ++-- deployment/eks/flyte_generated.yaml | 22 +-- .../flyte_helm_controlplane_generated.yaml | 20 +-- .../eks/flyte_helm_dataplane_generated.yaml | 14 +- deployment/eks/flyte_helm_generated.yaml | 34 ++-- .../flyte_helm_controlplane_generated.yaml | 20 +-- .../gcp/flyte_helm_dataplane_generated.yaml | 14 +- deployment/gcp/flyte_helm_generated.yaml | 34 ++-- .../flyte_sandbox_binary_helm_generated.yaml | 4 +- deployment/sandbox/flyte_helm_generated.yaml | 34 ++-- .../manifests/complete-agent.yaml | 8 +- .../sandbox-bundled/manifests/complete.yaml | 8 +- docker/sandbox-bundled/manifests/dev.yaml | 4 +- kustomize/overlays/eks/kustomization.yaml | 8 +- rsts/conf.py | 2 +- .../generated/flytepropeller_config.rst | 25 +++ 25 files changed, 343 insertions(+), 154 deletions(-) create mode 100644 CHANGELOG/CHANGELOG-v1.10.6.md diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 41ce00d103..9daac2a252 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -118,6 +118,8 @@ jobs: with: component: ${{ matrix.component }} go-version: ${{ needs.unpack-envvars.outputs.go-version }} + secrets: + FLYTE_BOT_PAT: ${{ secrets.FLYTE_BOT_PAT }} build_docker_images: name: Build Images diff --git a/.github/workflows/go_generate.yml b/.github/workflows/go_generate.yml index 79e60e29a0..5bb93ffc63 100644 --- a/.github/workflows/go_generate.yml +++ b/.github/workflows/go_generate.yml @@ -9,6 +9,9 @@ on: go-version: required: true type: string + secrets: + FLYTE_BOT_PAT: + required: true jobs: generate: runs-on: ubuntu-latest @@ -19,6 +22,8 @@ jobs: steps: - uses: actions/checkout@v3 - uses: arduino/setup-protoc@v1 + with: + repo-token: ${{ secrets.FLYTE_BOT_PAT }} - uses: bufbuild/buf-setup-action@v1 - uses: actions/setup-go@v3 with: diff --git a/CHANGELOG/CHANGELOG-v1.10.6.md b/CHANGELOG/CHANGELOG-v1.10.6.md new file mode 100644 index 0000000000..2aa4505998 --- /dev/null +++ b/CHANGELOG/CHANGELOG-v1.10.6.md @@ -0,0 +1,157 @@ +# Flyte 1.10.6 Release + +Due to a mishap in the move to the monorepo, we ended up generating the git tags between 1.10.1 to 1.10.5, so in order to decrease the confusion we decided to skip those patch versions and go straight to the next available version. + +We've shipped a ton of stuff in this patch release, here are some of the highlights. + +## GPU Accelerators +You'll be able to get more fine-grained in the use GPU Accelerators in your tasks. Here are some examples: + +No preference of GPU accelerator to use: +``` +@task(limits=Resources(gpu="1")) +def my_task() -> None: + ... +``` + +Schedule on a specific GPU accelerator: +``` +from flytekit.extras.accelerators import T4 + + +@task( + limits=Resources(gpu="1"), + accelerator=T4, +) +def my_task() -> None: + ... +``` + +Schedule on a Multi-instance GPU (MIG) accelerator with no preference of partition size: +``` +from flytekit.extras.accelerators import A100 + + +@task( + limits=Resources(gpu="1"), + accelerator=A100, +) +def my_task() -> None: + ... +``` + +Schedule on a Multi-instance GPU (MIG) accelerator with a specific partition size: +``` +from flytekit.extras.accelerators import A100 + + +@task( + limits=Resources(gpu="1"), + accelerator=A100.partition_1g_5gb, +) +def my_task() -> None: + ... +``` + +Schedule on an unpartitioned Multi-instance GPU (MIG) accelerator: +``` +from flytekit.extras.accelerators import A100 + + +@task( + limits=Resources(gpu="1"), + accelerator=A100.unpartitioned, +) +def my_task() -> None: + ... +``` + +## Improved support for Ray logs +https://github.com/flyteorg/flyte/pull/4266 opens the door for RayJob logs to be persisted. + +In https://github.com/flyteorg/flyte/pull/4397 we added support for a link to a Ray dashboard to show up in the task card. + +## Updated grafana dashboards +We updated the official grafana dashboards in https://github.com/flyteorg/flyte/pull/4382. + +## Support for Azure AD +A new version of our stow fork added support for Azure AD in https://github.com/flyteorg/stow/pull/9. + +## Full changelog: +* Restructure Flyte releases by @eapolinario in https://github.com/flyteorg/flyte/pull/4304 +* Use debian bookworm as single binary base image by @eapolinario in https://github.com/flyteorg/flyte/pull/4311 +* Use local version in single-binary by @eapolinario in https://github.com/flyteorg/flyte/pull/4294 +* Accessibility for README by @mishmanners in https://github.com/flyteorg/flyte/pull/4322 +* Add tests in `flytepropeller/pkg /controller/executors` from 72.3% to 87.3% coverage by @Future-Outlier in https://github.com/flyteorg/flyte/pull/4276 +* fix: remove unused setting in deployment charts by @HeetVekariya in https://github.com/flyteorg/flyte/pull/4252 +* Document simplified retry behaviour introduced in #3902 by @fg91 in https://github.com/flyteorg/flyte/pull/4022 +* Ray logs persistence by @jeevb in https://github.com/flyteorg/flyte/pull/4266 +* Not revisiting task nodes and correctly incrementing parallelism by @hamersaw in https://github.com/flyteorg/flyte/pull/4318 +* Fix RunPluginEndToEndTest util by @andresgomezfrr in https://github.com/flyteorg/flyte/pull/4342 +* Tune sandbox readiness checks to ensure that sandbox is fully accessi… by @jeevb in https://github.com/flyteorg/flyte/pull/4348 +* Chore: Ensure Stalebot doesn't close issues we've not yet triaged. by @brndnblck in https://github.com/flyteorg/flyte/pull/4352 +* Do not automatically close stale issues by @eapolinario in https://github.com/flyteorg/flyte/pull/4353 +* Fix: Set flyteadmin gRPC port to 80 in ingress if using TLS between load balancer and backend by @fg91 in https://github.com/flyteorg/flyte/pull/3964 +* Support Databricks WebAPI 2.1 version and Support `existing_cluster_id` and `new_cluster` options to create a Job by @Future-Outlier in https://github.com/flyteorg/flyte/pull/4361 +* Fixing caching on maptasks when using partials by @hamersaw in https://github.com/flyteorg/flyte/pull/4344 +* Fix read raw limit by @honnix in https://github.com/flyteorg/flyte/pull/4370 +* minor fix to eks-starter.yaml by @guyarad in https://github.com/flyteorg/flyte/pull/4337 +* Reporting running if the primary container status is not yet reported by @hamersaw in https://github.com/flyteorg/flyte/pull/4339 +* completing retries even if minSuccesses are achieved by @hamersaw in https://github.com/flyteorg/flyte/pull/4338 +* Add comment to auth scope by @wild-endeavor in https://github.com/flyteorg/flyte/pull/4341 +* Update tests by @eapolinario in https://github.com/flyteorg/flyte/pull/4381 +* Update order of cluster resources config to work with both uctl and flytectl by @neverett in https://github.com/flyteorg/flyte/pull/4373 +* Update tests in single-binary by @eapolinario in https://github.com/flyteorg/flyte/pull/4383 +* Passthrough unique node ID in task execution ID for generating log te… by @jeevb in https://github.com/flyteorg/flyte/pull/4380 +* Add Sections in the PR Template by @Future-Outlier in https://github.com/flyteorg/flyte/pull/4367 +* Update metadata in ArrayNode TaskExecutionEvents by @hamersaw in https://github.com/flyteorg/flyte/pull/4355 +* Fixes list formatting in flytepropeller arch docs by @thomasjpfan in https://github.com/flyteorg/flyte/pull/4345 +* Update boilerplate end2end tests by @hamersaw in https://github.com/flyteorg/flyte/pull/4393 +* Handle all ray job statuses by @EngHabu in https://github.com/flyteorg/flyte/pull/4389 +* Relocate sandbox config by @davidmirror-ops in https://github.com/flyteorg/flyte/pull/4385 +* Refactor task logs framework by @jeevb in https://github.com/flyteorg/flyte/pull/4396 +* Add support for displaying the Ray dashboard when a RayJob is active by @jeevb in https://github.com/flyteorg/flyte/pull/4397 +* Disable path filtering for monorepo components by @eapolinario in https://github.com/flyteorg/flyte/pull/4404 +* Silence NotFound when get task resource by @honnix in https://github.com/flyteorg/flyte/pull/4388 +* adding consoleUrl parameterization based on partition by @lauralindy in https://github.com/flyteorg/flyte/pull/4375 +* [Docs] Sensor Agent Doc by @Future-Outlier in https://github.com/flyteorg/flyte/pull/4195 +* [flytepropeller] Add Tests in v1alpha.go including `array_test.go`, `branch_test.go`, `error_test.go`, and `iface_test.go` with 0.13% Coverage Improvement by @Future-Outlier in https://github.com/flyteorg/flyte/pull/4234 +* Add more context for ray log template links by @jeevb in https://github.com/flyteorg/flyte/pull/4416 +* Add ClusterRole config for Ray by @davidmirror-ops in https://github.com/flyteorg/flyte/pull/4405 +* Fix and update scripts for generating grafana dashboards by @Tom-Newton in https://github.com/flyteorg/flyte/pull/4382 +* Add artifacts branch to publish to buf on push by @squiishyy in https://github.com/flyteorg/flyte/pull/4450 +* Add service monitor for flyte admin and propeller service by @vraiyaninv in https://github.com/flyteorg/flyte/pull/4427 +* Fix Kubeflow TF Operator `GetTaskPhase` Bug by @Future-Outlier in https://github.com/flyteorg/flyte/pull/4469 +* Instrument opentelemetry by @hamersaw in https://github.com/flyteorg/flyte/pull/4357 +* Delete the .github folder from each subdirectory by @pingsutw in https://github.com/flyteorg/flyte/pull/4480 +* Fix the loop variable scheduler issue by @pmahindrakar-oss in https://github.com/flyteorg/flyte/pull/4468 +* Databricks Plugin Setup Doc Enhancement by @Future-Outlier in https://github.com/flyteorg/flyte/pull/4445 +* Put ticker back in place in propeller gc by @eapolinario in https://github.com/flyteorg/flyte/pull/4490 +* Store failed execution in flyteadmin by @iaroslav-ciupin in https://github.com/flyteorg/flyte/pull/4390 +* Moving from flyteadmin - Upgrade coreos/go-oidc to v3 to pickup claims parsing fixes by @eapolinario in https://github.com/flyteorg/flyte/pull/4139 +* Bump flyteorg/stow to 0.3.8 by @eapolinario in https://github.com/flyteorg/flyte/pull/4312 +* Remove 'needs' from generate_flyte_manifest by @eapolinario in https://github.com/flyteorg/flyte/pull/4495 +* Update Flyte components by @flyte-bot in https://github.com/flyteorg/flyte/pull/4302 +* Modify how flytecopilot version is parsed from values file by @eapolinario in https://github.com/flyteorg/flyte/pull/4496 +* Ignore component tags in goreleaser by @eapolinario in https://github.com/flyteorg/flyte/pull/4497 +* Fix indentation of `shell: task` by @eapolinario in https://github.com/flyteorg/flyte/pull/4498 +* Implemented simple echo plugin for testing by @hamersaw in https://github.com/flyteorg/flyte/pull/4489 +* Correctly handle resource overrides in KF plugins by @jeevb in https://github.com/flyteorg/flyte/pull/4467 +* Remove deprecated InjectDecoder by @EngHabu in https://github.com/flyteorg/flyte/pull/4507 +* Fix $HOME resolution and webhook namespace by @EngHabu in https://github.com/flyteorg/flyte/pull/4509 +* Add note on updating sandbox cluster configuration by @jeevb in https://github.com/flyteorg/flyte/pull/4510 +* Add New PR Template by @Future-Outlier in https://github.com/flyteorg/flyte/pull/4512 +* [Docs] Databricks Agent Doc by @Future-Outlier in https://github.com/flyteorg/flyte/pull/4008 +* Bump version of goreleaser gh action to v5 by @eapolinario in https://github.com/flyteorg/flyte/pull/4519 +* Kf operators use `GetReplicaFunc` (Error Handling) by @Future-Outlier in https://github.com/flyteorg/flyte/pull/4471 + +## New Contributors +* @HeetVekariya made their first contribution in https://github.com/flyteorg/flyte/pull/4252 +* @andresgomezfrr made their first contribution in https://github.com/flyteorg/flyte/pull/4342 +* @brndnblck made their first contribution in https://github.com/flyteorg/flyte/pull/4352 +* @guyarad made their first contribution in https://github.com/flyteorg/flyte/pull/4337 +* @neverett made their first contribution in https://github.com/flyteorg/flyte/pull/4373 +* @thomasjpfan made their first contribution in https://github.com/flyteorg/flyte/pull/4345 +* @lauralindy made their first contribution in https://github.com/flyteorg/flyte/pull/4375 +* @Tom-Newton made their first contribution in https://github.com/flyteorg/flyte/pull/4382 +* @vraiyaninv made their first contribution in https://github.com/flyteorg/flyte/pull/4427 diff --git a/charts/flyte-binary/README.md b/charts/flyte-binary/README.md index 8a34c920a7..c4fa8cfc5e 100644 --- a/charts/flyte-binary/README.md +++ b/charts/flyte-binary/README.md @@ -42,7 +42,7 @@ Chart for basic single Flyte executable deployment | configuration.auth.oidc.clientId | string | `""` | | | configuration.auth.oidc.clientSecret | string | `""` | | | configuration.co-pilot.image.repository | string | `"cr.flyte.org/flyteorg/flytecopilot"` | | -| configuration.co-pilot.image.tag | string | `"v1.10.6-b0"` | | +| configuration.co-pilot.image.tag | string | `"v1.10.6"` | | | configuration.database.dbname | string | `"flyte"` | | | configuration.database.host | string | `"127.0.0.1"` | | | configuration.database.options | string | `"sslmode=disable"` | | diff --git a/charts/flyte-binary/values.yaml b/charts/flyte-binary/values.yaml index cbb86f8940..48ae2c47dd 100644 --- a/charts/flyte-binary/values.yaml +++ b/charts/flyte-binary/values.yaml @@ -159,7 +159,7 @@ configuration: # repository CoPilot sidecar image repository repository: cr.flyte.org/flyteorg/flytecopilot # FLYTECOPILOT_IMAGE # tag CoPilot sidecar image tag - tag: v1.10.6-b0 # FLYTECOPILOT_TAG + tag: v1.10.6 # FLYTECOPILOT_TAG # agentService Flyte Agent configuration agentService: defaultAgent: diff --git a/charts/flyte-core/README.md b/charts/flyte-core/README.md index f7c72d6c79..05b179c5d1 100644 --- a/charts/flyte-core/README.md +++ b/charts/flyte-core/README.md @@ -90,8 +90,8 @@ helm install gateway bitnami/contour -n flyte | configmap.clusters.clusterConfigs | list | `[]` | | | configmap.clusters.labelClusterMap | object | `{}` | | | configmap.console | object | `{"BASE_URL":"/console","CONFIG_DIR":"/etc/flyte/config"}` | Configuration for Flyte console UI | -| configmap.copilot | object | `{"plugins":{"k8s":{"co-pilot":{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0","name":"flyte-copilot-","start-timeout":"30s"}}}}` | Copilot configuration | -| configmap.copilot.plugins.k8s.co-pilot | object | `{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0","name":"flyte-copilot-","start-timeout":"30s"}` | Structure documented [here](https://pkg.go.dev/github.com/lyft/flyteplugins@v0.5.28/go/tasks/pluginmachinery/flytek8s/config#FlyteCoPilotConfig) | +| configmap.copilot | object | `{"plugins":{"k8s":{"co-pilot":{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6","name":"flyte-copilot-","start-timeout":"30s"}}}}` | Copilot configuration | +| configmap.copilot.plugins.k8s.co-pilot | object | `{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6","name":"flyte-copilot-","start-timeout":"30s"}` | Structure documented [here](https://pkg.go.dev/github.com/lyft/flyteplugins@v0.5.28/go/tasks/pluginmachinery/flytek8s/config#FlyteCoPilotConfig) | | configmap.core | object | `{"manager":{"pod-application":"flytepropeller","pod-template-container-name":"flytepropeller","pod-template-name":"flytepropeller-template"},"propeller":{"downstream-eval-duration":"30s","enable-admin-launcher":true,"leader-election":{"enabled":true,"lease-duration":"15s","lock-config-map":{"name":"propeller-leader","namespace":"flyte"},"renew-deadline":"10s","retry-period":"2s"},"limit-namespace":"all","max-workflow-retries":30,"metadata-prefix":"metadata/propeller","metrics-prefix":"flyte","prof-port":10254,"queue":{"batch-size":-1,"batching-interval":"2s","queue":{"base-delay":"5s","capacity":1000,"max-delay":"120s","rate":100,"type":"maxof"},"sub-queue":{"capacity":100,"rate":10,"type":"bucket"},"type":"batch"},"rawoutput-prefix":"s3://my-s3-bucket/","workers":4,"workflow-reeval-duration":"30s"},"webhook":{"certDir":"/etc/webhook/certs","serviceName":"flyte-pod-webhook"}}` | Core propeller configuration | | configmap.core.manager | object | `{"pod-application":"flytepropeller","pod-template-container-name":"flytepropeller","pod-template-name":"flytepropeller-template"}` | follows the structure specified [here](https://pkg.go.dev/github.com/flyteorg/flytepropeller/manager/config#Config). | | configmap.core.propeller | object | `{"downstream-eval-duration":"30s","enable-admin-launcher":true,"leader-election":{"enabled":true,"lease-duration":"15s","lock-config-map":{"name":"propeller-leader","namespace":"flyte"},"renew-deadline":"10s","retry-period":"2s"},"limit-namespace":"all","max-workflow-retries":30,"metadata-prefix":"metadata/propeller","metrics-prefix":"flyte","prof-port":10254,"queue":{"batch-size":-1,"batching-interval":"2s","queue":{"base-delay":"5s","capacity":1000,"max-delay":"120s","rate":100,"type":"maxof"},"sub-queue":{"capacity":100,"rate":10,"type":"bucket"},"type":"batch"},"rawoutput-prefix":"s3://my-s3-bucket/","workers":4,"workflow-reeval-duration":"30s"}` | follows the structure specified [here](https://pkg.go.dev/github.com/flyteorg/flytepropeller/pkg/controller/config). | @@ -125,7 +125,7 @@ helm install gateway bitnami/contour -n flyte | datacatalog.extraArgs | object | `{}` | Appends extra command line arguments to the main command | | datacatalog.image.pullPolicy | string | `"IfNotPresent"` | Docker image pull policy | | datacatalog.image.repository | string | `"cr.flyte.org/flyteorg/datacatalog"` | Docker image for Datacatalog deployment | -| datacatalog.image.tag | string | `"v1.10.6-b0"` | Docker image tag | +| datacatalog.image.tag | string | `"v1.10.6"` | Docker image tag | | datacatalog.nodeSelector | object | `{}` | nodeSelector for Datacatalog deployment | | datacatalog.podAnnotations | object | `{}` | Annotations for Datacatalog pods | | datacatalog.priorityClassName | string | `""` | Sets priorityClassName for datacatalog pod(s). | @@ -157,7 +157,7 @@ helm install gateway bitnami/contour -n flyte | flyteadmin.extraArgs | object | `{}` | Appends extra command line arguments to the serve command | | flyteadmin.image.pullPolicy | string | `"IfNotPresent"` | | | flyteadmin.image.repository | string | `"cr.flyte.org/flyteorg/flyteadmin"` | Docker image for Flyteadmin deployment | -| flyteadmin.image.tag | string | `"v1.10.6-b0"` | | +| flyteadmin.image.tag | string | `"v1.10.6"` | | | flyteadmin.initialProjects | list | `["flytesnacks","flytetester","flyteexamples"]` | Initial projects to create | | flyteadmin.nodeSelector | object | `{}` | nodeSelector for Flyteadmin deployment | | flyteadmin.podAnnotations | object | `{}` | Annotations for Flyteadmin pods | @@ -209,7 +209,7 @@ helm install gateway bitnami/contour -n flyte | flytepropeller.extraArgs | object | `{}` | Appends extra command line arguments to the main command | | flytepropeller.image.pullPolicy | string | `"IfNotPresent"` | | | flytepropeller.image.repository | string | `"cr.flyte.org/flyteorg/flytepropeller"` | Docker image for Flytepropeller deployment | -| flytepropeller.image.tag | string | `"v1.10.6-b0"` | | +| flytepropeller.image.tag | string | `"v1.10.6"` | | | flytepropeller.manager | bool | `false` | | | flytepropeller.nodeSelector | object | `{}` | nodeSelector for Flytepropeller deployment | | flytepropeller.podAnnotations | object | `{}` | Annotations for Flytepropeller pods | @@ -236,7 +236,7 @@ helm install gateway bitnami/contour -n flyte | flytescheduler.configPath | string | `"/etc/flyte/config/*.yaml"` | Default regex string for searching configuration files | | flytescheduler.image.pullPolicy | string | `"IfNotPresent"` | Docker image pull policy | | flytescheduler.image.repository | string | `"cr.flyte.org/flyteorg/flytescheduler"` | Docker image for Flytescheduler deployment | -| flytescheduler.image.tag | string | `"v1.10.6-b0"` | Docker image tag | +| flytescheduler.image.tag | string | `"v1.10.6"` | Docker image tag | | flytescheduler.nodeSelector | object | `{}` | nodeSelector for Flytescheduler deployment | | flytescheduler.podAnnotations | object | `{}` | Annotations for Flytescheduler pods | | flytescheduler.priorityClassName | string | `""` | Sets priorityClassName for flyte scheduler pod(s). | diff --git a/charts/flyte-core/values.yaml b/charts/flyte-core/values.yaml index 448787b39b..d09d9f9824 100755 --- a/charts/flyte-core/values.yaml +++ b/charts/flyte-core/values.yaml @@ -16,7 +16,7 @@ flyteadmin: image: # -- Docker image for Flyteadmin deployment repository: cr.flyte.org/flyteorg/flyteadmin # FLYTEADMIN_IMAGE - tag: v1.10.6-b0 # FLYTEADMIN_TAG + tag: v1.10.6 # FLYTEADMIN_TAG pullPolicy: IfNotPresent # -- Additional flyteadmin container environment variables # @@ -132,7 +132,7 @@ flytescheduler: # -- Docker image for Flytescheduler deployment repository: cr.flyte.org/flyteorg/flytescheduler # FLYTESCHEDULER_IMAGE # -- Docker image tag - tag: v1.10.6-b0 # FLYTESCHEDULER_TAG + tag: v1.10.6 # FLYTESCHEDULER_TAG # -- Docker image pull policy pullPolicy: IfNotPresent # -- Default resources requests and limits for Flytescheduler deployment @@ -186,7 +186,7 @@ datacatalog: # -- Docker image for Datacatalog deployment repository: cr.flyte.org/flyteorg/datacatalog # DATACATALOG_IMAGE # -- Docker image tag - tag: v1.10.6-b0 # DATACATALOG_TAG + tag: v1.10.6 # DATACATALOG_TAG # -- Docker image pull policy pullPolicy: IfNotPresent # -- Default resources requests and limits for Datacatalog deployment @@ -254,7 +254,7 @@ flytepropeller: image: # -- Docker image for Flytepropeller deployment repository: cr.flyte.org/flyteorg/flytepropeller # FLYTEPROPELLER_IMAGE - tag: v1.10.6-b0 # FLYTEPROPELLER_TAG + tag: v1.10.6 # FLYTEPROPELLER_TAG pullPolicy: IfNotPresent # -- Default resources requests and limits for Flytepropeller deployment resources: @@ -654,7 +654,7 @@ configmap: # -- Structure documented [here](https://pkg.go.dev/github.com/lyft/flyteplugins@v0.5.28/go/tasks/pluginmachinery/flytek8s/config#FlyteCoPilotConfig) co-pilot: name: flyte-copilot- - image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0 # FLYTECOPILOT_IMAGE + image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6 # FLYTECOPILOT_IMAGE start-timeout: 30s # -- Core propeller configuration diff --git a/charts/flyte/README.md b/charts/flyte/README.md index 246fd18907..d4a46ff286 100644 --- a/charts/flyte/README.md +++ b/charts/flyte/README.md @@ -71,7 +71,7 @@ helm upgrade -f values-sandbox.yaml flyte . | contour.tolerations | list | `[]` | tolerations for Contour deployment | | daskoperator | object | `{"enabled":false}` | Optional: Dask Plugin using the Dask Operator | | daskoperator.enabled | bool | `false` | - enable or disable the dask operator deployment installation | -| flyte | object | `{"cluster_resource_manager":{"config":{"cluster_resources":{"customData":[{"production":[{"projectQuotaCpu":{"value":"5"}},{"projectQuotaMemory":{"value":"4000Mi"}}]},{"staging":[{"projectQuotaCpu":{"value":"2"}},{"projectQuotaMemory":{"value":"3000Mi"}}]},{"development":[{"projectQuotaCpu":{"value":"4"}},{"projectQuotaMemory":{"value":"3000Mi"}}]}],"refresh":"5m","refreshInterval":"5m","standaloneDeployment":false,"templatePath":"/etc/flyte/clusterresource/templates"}},"enabled":true,"service_account_name":"flyteadmin","templates":[{"key":"aa_namespace","value":"apiVersion: v1\nkind: Namespace\nmetadata:\n name: {{ namespace }}\nspec:\n finalizers:\n - kubernetes\n"},{"key":"ab_project_resource_quota","value":"apiVersion: v1\nkind: ResourceQuota\nmetadata:\n name: project-quota\n namespace: {{ namespace }}\nspec:\n hard:\n limits.cpu: {{ projectQuotaCpu }}\n limits.memory: {{ projectQuotaMemory }}\n"}]},"common":{"databaseSecret":{"name":"","secretManifest":{}},"flyteNamespaceTemplate":{"enabled":false},"ingress":{"albSSLRedirect":false,"annotations":{"nginx.ingress.kubernetes.io/app-root":"/console"},"enabled":true,"host":"","separateGrpcIngress":false,"separateGrpcIngressAnnotations":{"nginx.ingress.kubernetes.io/backend-protocol":"GRPC"},"tls":{"enabled":false},"webpackHMR":true}},"configmap":{"adminServer":{"auth":{"appAuth":{"thirdPartyConfig":{"flyteClient":{"clientId":"flytectl","redirectUri":"http://localhost:53593/callback","scopes":["offline","all"]}}},"authorizedUris":["https://localhost:30081","http://flyteadmin:80","http://flyteadmin.flyte.svc.cluster.local:80"],"userAuth":{"openId":{"baseUrl":"https://accounts.google.com","clientId":"657465813211-6eog7ek7li5k7i7fvgv2921075063hpe.apps.googleusercontent.com","scopes":["profile","openid"]}}},"flyteadmin":{"eventVersion":2,"metadataStoragePrefix":["metadata","admin"],"metricsScope":"flyte:","profilerPort":10254,"roleNameKey":"iam.amazonaws.com/role","testing":{"host":"http://flyteadmin"}},"server":{"grpcPort":8089,"httpPort":8088,"security":{"allowCors":true,"allowedHeaders":["Content-Type","flyte-authorization"],"allowedOrigins":["*"],"secure":false,"useAuth":false}}},"catalog":{"catalog-cache":{"endpoint":"datacatalog:89","insecure":true,"type":"datacatalog"}},"console":{"BASE_URL":"/console","CONFIG_DIR":"/etc/flyte/config"},"copilot":{"plugins":{"k8s":{"co-pilot":{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0","name":"flyte-copilot-","start-timeout":"30s"}}}},"core":{"propeller":{"downstream-eval-duration":"30s","enable-admin-launcher":true,"leader-election":{"enabled":true,"lease-duration":"15s","lock-config-map":{"name":"propeller-leader","namespace":"flyte"},"renew-deadline":"10s","retry-period":"2s"},"limit-namespace":"all","max-workflow-retries":30,"metadata-prefix":"metadata/propeller","metrics-prefix":"flyte","prof-port":10254,"queue":{"batch-size":-1,"batching-interval":"2s","queue":{"base-delay":"5s","capacity":1000,"max-delay":"120s","rate":100,"type":"maxof"},"sub-queue":{"capacity":100,"rate":10,"type":"bucket"},"type":"batch"},"rawoutput-prefix":"s3://my-s3-bucket/","workers":4,"workflow-reeval-duration":"30s"},"webhook":{"certDir":"/etc/webhook/certs","serviceName":"flyte-pod-webhook"}},"datacatalogServer":{"application":{"grpcPort":8089,"grpcServerReflection":true,"httpPort":8080},"datacatalog":{"metrics-scope":"datacatalog","profiler-port":10254,"storage-prefix":"metadata/datacatalog"}},"domain":{"domains":[{"id":"development","name":"development"},{"id":"staging","name":"staging"},{"id":"production","name":"production"}]},"enabled_plugins":{"tasks":{"task-plugins":{"default-for-task-types":{"bigquery_query_job_task":"agent-service","container":"container","container_array":"k8s-array","sidecar":"sidecar"},"enabled-plugins":["container","sidecar","k8s-array","agent-service"]}}},"k8s":{"plugins":{"agent-service":{"defaultAgent":{"endpoint":"dns:///flyteagent.flyte.svc.cluster.local:8000","insecure":true},"supportedTaskTypes":["bigquery_query_job_task"]},"k8s":{"default-cpus":"100m","default-env-vars":[{"FLYTE_AWS_ENDPOINT":"http://minio.flyte:9000"},{"FLYTE_AWS_ACCESS_KEY_ID":"minio"},{"FLYTE_AWS_SECRET_ACCESS_KEY":"miniostorage"}],"default-memory":"200Mi"}}},"logger":{"logger":{"level":5,"show-source":true}},"remoteData":{"remoteData":{"region":"us-east-1","scheme":"local","signedUrls":{"durationMinutes":3}}},"resource_manager":{"propeller":{"resourcemanager":{"redis":null,"type":"noop"}}},"task_logs":{"plugins":{"logs":{"cloudwatch-enabled":false,"kubernetes-enabled":true,"kubernetes-template-uri":"http://localhost:30082/#/log/{{ \"{{\" }} .namespace {{ \"}}\" }}/{{ \"{{\" }} .podName {{ \"}}\" }}/pod?namespace={{ \"{{\" }} .namespace {{ \"}}\" }}"}}},"task_resource_defaults":{"task_resources":{"defaults":{"cpu":"100m","memory":"200Mi","storage":"5Mi"},"limits":{"cpu":2,"gpu":1,"memory":"1Gi","storage":"20Mi"}}}},"datacatalog":{"affinity":{},"configPath":"/etc/datacatalog/config/*.yaml","image":{"pullPolicy":"IfNotPresent","repository":"cr.flyte.org/flyteorg/datacatalog","tag":"v1.10.6-b0"},"nodeSelector":{},"podAnnotations":{},"replicaCount":1,"resources":{"limits":{"cpu":"500m","ephemeral-storage":"100Mi","memory":"500Mi"},"requests":{"cpu":"10m","ephemeral-storage":"50Mi","memory":"50Mi"}},"service":{"annotations":{"projectcontour.io/upstream-protocol.h2c":"grpc"},"type":"NodePort"},"serviceAccount":{"annotations":{},"create":true,"imagePullSecrets":[]},"tolerations":[]},"db":{"admin":{"database":{"dbname":"flyteadmin","host":"postgres","port":5432,"username":"postgres"}},"datacatalog":{"database":{"dbname":"datacatalog","host":"postgres","port":5432,"username":"postgres"}}},"deployRedoc":true,"flyteadmin":{"additionalVolumeMounts":[],"additionalVolumes":[],"affinity":{},"configPath":"/etc/flyte/config/*.yaml","env":[],"image":{"pullPolicy":"IfNotPresent","repository":"cr.flyte.org/flyteorg/flyteadmin","tag":"v1.10.6-b0"},"initialProjects":["flytesnacks","flytetester","flyteexamples"],"nodeSelector":{},"podAnnotations":{},"replicaCount":1,"resources":{"limits":{"cpu":"250m","ephemeral-storage":"100Mi","memory":"500Mi"},"requests":{"cpu":"10m","ephemeral-storage":"50Mi","memory":"50Mi"}},"secrets":{},"service":{"annotations":{"projectcontour.io/upstream-protocol.h2c":"grpc"},"loadBalancerSourceRanges":[],"type":"ClusterIP"},"serviceAccount":{"annotations":{},"create":true,"imagePullSecrets":[]},"tolerations":[]},"flyteconsole":{"affinity":{},"ga":{"enabled":true,"tracking_id":"G-0QW4DJWJ20"},"image":{"pullPolicy":"IfNotPresent","repository":"cr.flyte.org/flyteorg/flyteconsole","tag":"v1.10.2"},"nodeSelector":{},"podAnnotations":{},"replicaCount":1,"resources":{"limits":{"cpu":"500m","memory":"275Mi"},"requests":{"cpu":"10m","memory":"250Mi"}},"service":{"annotations":{},"type":"ClusterIP"},"tolerations":[]},"flytepropeller":{"affinity":{},"cacheSizeMbs":0,"configPath":"/etc/flyte/config/*.yaml","image":{"pullPolicy":"IfNotPresent","repository":"cr.flyte.org/flyteorg/flytepropeller","tag":"v1.10.6-b0"},"manager":false,"nodeSelector":{},"podAnnotations":{},"replicaCount":1,"resources":{"limits":{"cpu":"200m","ephemeral-storage":"100Mi","memory":"200Mi"},"requests":{"cpu":"10m","ephemeral-storage":"50Mi","memory":"50Mi"}},"serviceAccount":{"annotations":{},"create":true,"imagePullSecrets":[]},"tolerations":[]},"flytescheduler":{"affinity":{},"configPath":"/etc/flyte/config/*.yaml","image":{"pullPolicy":"IfNotPresent","repository":"cr.flyte.org/flyteorg/flytescheduler","tag":"v1.10.6-b0"},"nodeSelector":{},"podAnnotations":{},"resources":{"limits":{"cpu":"250m","ephemeral-storage":"100Mi","memory":"500Mi"},"requests":{"cpu":"10m","ephemeral-storage":"50Mi","memory":"50Mi"}},"secrets":{},"serviceAccount":{"annotations":{},"create":true,"imagePullSecrets":[]},"tolerations":[]},"storage":{"bucketName":"my-s3-bucket","custom":{},"gcs":null,"s3":{"region":"us-east-1"},"type":"sandbox"},"webhook":{"enabled":true,"service":{"annotations":{"projectcontour.io/upstream-protocol.h2c":"grpc"},"type":"ClusterIP"},"serviceAccount":{"annotations":{},"create":true,"imagePullSecrets":[]}},"workflow_notifications":{"config":{},"enabled":false},"workflow_scheduler":{"enabled":true,"type":"native"}}` | ------------------------------------------------------------------- Core System settings This section consists of Core components of Flyte and their deployment settings. This includes FlyteAdmin service, Datacatalog, FlytePropeller and Flyteconsole | +| flyte | object | `{"cluster_resource_manager":{"config":{"cluster_resources":{"customData":[{"production":[{"projectQuotaCpu":{"value":"5"}},{"projectQuotaMemory":{"value":"4000Mi"}}]},{"staging":[{"projectQuotaCpu":{"value":"2"}},{"projectQuotaMemory":{"value":"3000Mi"}}]},{"development":[{"projectQuotaCpu":{"value":"4"}},{"projectQuotaMemory":{"value":"3000Mi"}}]}],"refresh":"5m","refreshInterval":"5m","standaloneDeployment":false,"templatePath":"/etc/flyte/clusterresource/templates"}},"enabled":true,"service_account_name":"flyteadmin","templates":[{"key":"aa_namespace","value":"apiVersion: v1\nkind: Namespace\nmetadata:\n name: {{ namespace }}\nspec:\n finalizers:\n - kubernetes\n"},{"key":"ab_project_resource_quota","value":"apiVersion: v1\nkind: ResourceQuota\nmetadata:\n name: project-quota\n namespace: {{ namespace }}\nspec:\n hard:\n limits.cpu: {{ projectQuotaCpu }}\n limits.memory: {{ projectQuotaMemory }}\n"}]},"common":{"databaseSecret":{"name":"","secretManifest":{}},"flyteNamespaceTemplate":{"enabled":false},"ingress":{"albSSLRedirect":false,"annotations":{"nginx.ingress.kubernetes.io/app-root":"/console"},"enabled":true,"host":"","separateGrpcIngress":false,"separateGrpcIngressAnnotations":{"nginx.ingress.kubernetes.io/backend-protocol":"GRPC"},"tls":{"enabled":false},"webpackHMR":true}},"configmap":{"adminServer":{"auth":{"appAuth":{"thirdPartyConfig":{"flyteClient":{"clientId":"flytectl","redirectUri":"http://localhost:53593/callback","scopes":["offline","all"]}}},"authorizedUris":["https://localhost:30081","http://flyteadmin:80","http://flyteadmin.flyte.svc.cluster.local:80"],"userAuth":{"openId":{"baseUrl":"https://accounts.google.com","clientId":"657465813211-6eog7ek7li5k7i7fvgv2921075063hpe.apps.googleusercontent.com","scopes":["profile","openid"]}}},"flyteadmin":{"eventVersion":2,"metadataStoragePrefix":["metadata","admin"],"metricsScope":"flyte:","profilerPort":10254,"roleNameKey":"iam.amazonaws.com/role","testing":{"host":"http://flyteadmin"}},"server":{"grpcPort":8089,"httpPort":8088,"security":{"allowCors":true,"allowedHeaders":["Content-Type","flyte-authorization"],"allowedOrigins":["*"],"secure":false,"useAuth":false}}},"catalog":{"catalog-cache":{"endpoint":"datacatalog:89","insecure":true,"type":"datacatalog"}},"console":{"BASE_URL":"/console","CONFIG_DIR":"/etc/flyte/config"},"copilot":{"plugins":{"k8s":{"co-pilot":{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6","name":"flyte-copilot-","start-timeout":"30s"}}}},"core":{"propeller":{"downstream-eval-duration":"30s","enable-admin-launcher":true,"leader-election":{"enabled":true,"lease-duration":"15s","lock-config-map":{"name":"propeller-leader","namespace":"flyte"},"renew-deadline":"10s","retry-period":"2s"},"limit-namespace":"all","max-workflow-retries":30,"metadata-prefix":"metadata/propeller","metrics-prefix":"flyte","prof-port":10254,"queue":{"batch-size":-1,"batching-interval":"2s","queue":{"base-delay":"5s","capacity":1000,"max-delay":"120s","rate":100,"type":"maxof"},"sub-queue":{"capacity":100,"rate":10,"type":"bucket"},"type":"batch"},"rawoutput-prefix":"s3://my-s3-bucket/","workers":4,"workflow-reeval-duration":"30s"},"webhook":{"certDir":"/etc/webhook/certs","serviceName":"flyte-pod-webhook"}},"datacatalogServer":{"application":{"grpcPort":8089,"grpcServerReflection":true,"httpPort":8080},"datacatalog":{"metrics-scope":"datacatalog","profiler-port":10254,"storage-prefix":"metadata/datacatalog"}},"domain":{"domains":[{"id":"development","name":"development"},{"id":"staging","name":"staging"},{"id":"production","name":"production"}]},"enabled_plugins":{"tasks":{"task-plugins":{"default-for-task-types":{"bigquery_query_job_task":"agent-service","container":"container","container_array":"k8s-array","sidecar":"sidecar"},"enabled-plugins":["container","sidecar","k8s-array","agent-service"]}}},"k8s":{"plugins":{"agent-service":{"defaultAgent":{"endpoint":"dns:///flyteagent.flyte.svc.cluster.local:8000","insecure":true},"supportedTaskTypes":["bigquery_query_job_task"]},"k8s":{"default-cpus":"100m","default-env-vars":[{"FLYTE_AWS_ENDPOINT":"http://minio.flyte:9000"},{"FLYTE_AWS_ACCESS_KEY_ID":"minio"},{"FLYTE_AWS_SECRET_ACCESS_KEY":"miniostorage"}],"default-memory":"200Mi"}}},"logger":{"logger":{"level":5,"show-source":true}},"remoteData":{"remoteData":{"region":"us-east-1","scheme":"local","signedUrls":{"durationMinutes":3}}},"resource_manager":{"propeller":{"resourcemanager":{"redis":null,"type":"noop"}}},"task_logs":{"plugins":{"logs":{"cloudwatch-enabled":false,"kubernetes-enabled":true,"kubernetes-template-uri":"http://localhost:30082/#/log/{{ \"{{\" }} .namespace {{ \"}}\" }}/{{ \"{{\" }} .podName {{ \"}}\" }}/pod?namespace={{ \"{{\" }} .namespace {{ \"}}\" }}"}}},"task_resource_defaults":{"task_resources":{"defaults":{"cpu":"100m","memory":"200Mi","storage":"5Mi"},"limits":{"cpu":2,"gpu":1,"memory":"1Gi","storage":"20Mi"}}}},"datacatalog":{"affinity":{},"configPath":"/etc/datacatalog/config/*.yaml","image":{"pullPolicy":"IfNotPresent","repository":"cr.flyte.org/flyteorg/datacatalog","tag":"v1.10.6"},"nodeSelector":{},"podAnnotations":{},"replicaCount":1,"resources":{"limits":{"cpu":"500m","ephemeral-storage":"100Mi","memory":"500Mi"},"requests":{"cpu":"10m","ephemeral-storage":"50Mi","memory":"50Mi"}},"service":{"annotations":{"projectcontour.io/upstream-protocol.h2c":"grpc"},"type":"NodePort"},"serviceAccount":{"annotations":{},"create":true,"imagePullSecrets":[]},"tolerations":[]},"db":{"admin":{"database":{"dbname":"flyteadmin","host":"postgres","port":5432,"username":"postgres"}},"datacatalog":{"database":{"dbname":"datacatalog","host":"postgres","port":5432,"username":"postgres"}}},"deployRedoc":true,"flyteadmin":{"additionalVolumeMounts":[],"additionalVolumes":[],"affinity":{},"configPath":"/etc/flyte/config/*.yaml","env":[],"image":{"pullPolicy":"IfNotPresent","repository":"cr.flyte.org/flyteorg/flyteadmin","tag":"v1.10.6"},"initialProjects":["flytesnacks","flytetester","flyteexamples"],"nodeSelector":{},"podAnnotations":{},"replicaCount":1,"resources":{"limits":{"cpu":"250m","ephemeral-storage":"100Mi","memory":"500Mi"},"requests":{"cpu":"10m","ephemeral-storage":"50Mi","memory":"50Mi"}},"secrets":{},"service":{"annotations":{"projectcontour.io/upstream-protocol.h2c":"grpc"},"loadBalancerSourceRanges":[],"type":"ClusterIP"},"serviceAccount":{"annotations":{},"create":true,"imagePullSecrets":[]},"tolerations":[]},"flyteconsole":{"affinity":{},"ga":{"enabled":true,"tracking_id":"G-0QW4DJWJ20"},"image":{"pullPolicy":"IfNotPresent","repository":"cr.flyte.org/flyteorg/flyteconsole","tag":"v1.10.2"},"nodeSelector":{},"podAnnotations":{},"replicaCount":1,"resources":{"limits":{"cpu":"500m","memory":"275Mi"},"requests":{"cpu":"10m","memory":"250Mi"}},"service":{"annotations":{},"type":"ClusterIP"},"tolerations":[]},"flytepropeller":{"affinity":{},"cacheSizeMbs":0,"configPath":"/etc/flyte/config/*.yaml","image":{"pullPolicy":"IfNotPresent","repository":"cr.flyte.org/flyteorg/flytepropeller","tag":"v1.10.6"},"manager":false,"nodeSelector":{},"podAnnotations":{},"replicaCount":1,"resources":{"limits":{"cpu":"200m","ephemeral-storage":"100Mi","memory":"200Mi"},"requests":{"cpu":"10m","ephemeral-storage":"50Mi","memory":"50Mi"}},"serviceAccount":{"annotations":{},"create":true,"imagePullSecrets":[]},"tolerations":[]},"flytescheduler":{"affinity":{},"configPath":"/etc/flyte/config/*.yaml","image":{"pullPolicy":"IfNotPresent","repository":"cr.flyte.org/flyteorg/flytescheduler","tag":"v1.10.6"},"nodeSelector":{},"podAnnotations":{},"resources":{"limits":{"cpu":"250m","ephemeral-storage":"100Mi","memory":"500Mi"},"requests":{"cpu":"10m","ephemeral-storage":"50Mi","memory":"50Mi"}},"secrets":{},"serviceAccount":{"annotations":{},"create":true,"imagePullSecrets":[]},"tolerations":[]},"storage":{"bucketName":"my-s3-bucket","custom":{},"gcs":null,"s3":{"region":"us-east-1"},"type":"sandbox"},"webhook":{"enabled":true,"service":{"annotations":{"projectcontour.io/upstream-protocol.h2c":"grpc"},"type":"ClusterIP"},"serviceAccount":{"annotations":{},"create":true,"imagePullSecrets":[]}},"workflow_notifications":{"config":{},"enabled":false},"workflow_scheduler":{"enabled":true,"type":"native"}}` | ------------------------------------------------------------------- Core System settings This section consists of Core components of Flyte and their deployment settings. This includes FlyteAdmin service, Datacatalog, FlytePropeller and Flyteconsole | | flyte.cluster_resource_manager | object | `{"config":{"cluster_resources":{"customData":[{"production":[{"projectQuotaCpu":{"value":"5"}},{"projectQuotaMemory":{"value":"4000Mi"}}]},{"staging":[{"projectQuotaCpu":{"value":"2"}},{"projectQuotaMemory":{"value":"3000Mi"}}]},{"development":[{"projectQuotaCpu":{"value":"4"}},{"projectQuotaMemory":{"value":"3000Mi"}}]}],"refresh":"5m","refreshInterval":"5m","standaloneDeployment":false,"templatePath":"/etc/flyte/clusterresource/templates"}},"enabled":true,"service_account_name":"flyteadmin","templates":[{"key":"aa_namespace","value":"apiVersion: v1\nkind: Namespace\nmetadata:\n name: {{ namespace }}\nspec:\n finalizers:\n - kubernetes\n"},{"key":"ab_project_resource_quota","value":"apiVersion: v1\nkind: ResourceQuota\nmetadata:\n name: project-quota\n namespace: {{ namespace }}\nspec:\n hard:\n limits.cpu: {{ projectQuotaCpu }}\n limits.memory: {{ projectQuotaMemory }}\n"}]}` | Configuration for the Cluster resource manager component. This is an optional component, that enables automatic cluster configuration. This is useful to set default quotas, manage namespaces etc that map to a project/domain | | flyte.cluster_resource_manager.config.cluster_resources | object | `{"customData":[{"production":[{"projectQuotaCpu":{"value":"5"}},{"projectQuotaMemory":{"value":"4000Mi"}}]},{"staging":[{"projectQuotaCpu":{"value":"2"}},{"projectQuotaMemory":{"value":"3000Mi"}}]},{"development":[{"projectQuotaCpu":{"value":"4"}},{"projectQuotaMemory":{"value":"3000Mi"}}]}],"refresh":"5m","refreshInterval":"5m","standaloneDeployment":false,"templatePath":"/etc/flyte/clusterresource/templates"}` | ClusterResource parameters Refer to the [structure](https://pkg.go.dev/github.com/lyft/flyteadmin@v0.3.37/pkg/runtime/interfaces#ClusterResourceConfig) to customize. | | flyte.cluster_resource_manager.config.cluster_resources.standaloneDeployment | bool | `false` | Starts the cluster resource manager in standalone mode with requisite auth credentials to call flyteadmin service endpoints | @@ -91,15 +91,15 @@ helm upgrade -f values-sandbox.yaml flyte . | flyte.common.ingress.separateGrpcIngressAnnotations | object | `{"nginx.ingress.kubernetes.io/backend-protocol":"GRPC"}` | - Extra Ingress annotations applied only to the GRPC ingress. Only makes sense if `separateGrpcIngress` is enabled. | | flyte.common.ingress.tls | object | `{"enabled":false}` | - TLS Settings | | flyte.common.ingress.webpackHMR | bool | `true` | - Enable or disable HMR route to flyteconsole. This is useful only for frontend development. | -| flyte.configmap | object | `{"adminServer":{"auth":{"appAuth":{"thirdPartyConfig":{"flyteClient":{"clientId":"flytectl","redirectUri":"http://localhost:53593/callback","scopes":["offline","all"]}}},"authorizedUris":["https://localhost:30081","http://flyteadmin:80","http://flyteadmin.flyte.svc.cluster.local:80"],"userAuth":{"openId":{"baseUrl":"https://accounts.google.com","clientId":"657465813211-6eog7ek7li5k7i7fvgv2921075063hpe.apps.googleusercontent.com","scopes":["profile","openid"]}}},"flyteadmin":{"eventVersion":2,"metadataStoragePrefix":["metadata","admin"],"metricsScope":"flyte:","profilerPort":10254,"roleNameKey":"iam.amazonaws.com/role","testing":{"host":"http://flyteadmin"}},"server":{"grpcPort":8089,"httpPort":8088,"security":{"allowCors":true,"allowedHeaders":["Content-Type","flyte-authorization"],"allowedOrigins":["*"],"secure":false,"useAuth":false}}},"catalog":{"catalog-cache":{"endpoint":"datacatalog:89","insecure":true,"type":"datacatalog"}},"console":{"BASE_URL":"/console","CONFIG_DIR":"/etc/flyte/config"},"copilot":{"plugins":{"k8s":{"co-pilot":{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0","name":"flyte-copilot-","start-timeout":"30s"}}}},"core":{"propeller":{"downstream-eval-duration":"30s","enable-admin-launcher":true,"leader-election":{"enabled":true,"lease-duration":"15s","lock-config-map":{"name":"propeller-leader","namespace":"flyte"},"renew-deadline":"10s","retry-period":"2s"},"limit-namespace":"all","max-workflow-retries":30,"metadata-prefix":"metadata/propeller","metrics-prefix":"flyte","prof-port":10254,"queue":{"batch-size":-1,"batching-interval":"2s","queue":{"base-delay":"5s","capacity":1000,"max-delay":"120s","rate":100,"type":"maxof"},"sub-queue":{"capacity":100,"rate":10,"type":"bucket"},"type":"batch"},"rawoutput-prefix":"s3://my-s3-bucket/","workers":4,"workflow-reeval-duration":"30s"},"webhook":{"certDir":"/etc/webhook/certs","serviceName":"flyte-pod-webhook"}},"datacatalogServer":{"application":{"grpcPort":8089,"grpcServerReflection":true,"httpPort":8080},"datacatalog":{"metrics-scope":"datacatalog","profiler-port":10254,"storage-prefix":"metadata/datacatalog"}},"domain":{"domains":[{"id":"development","name":"development"},{"id":"staging","name":"staging"},{"id":"production","name":"production"}]},"enabled_plugins":{"tasks":{"task-plugins":{"default-for-task-types":{"bigquery_query_job_task":"agent-service","container":"container","container_array":"k8s-array","sidecar":"sidecar"},"enabled-plugins":["container","sidecar","k8s-array","agent-service"]}}},"k8s":{"plugins":{"agent-service":{"defaultAgent":{"endpoint":"dns:///flyteagent.flyte.svc.cluster.local:8000","insecure":true},"supportedTaskTypes":["bigquery_query_job_task"]},"k8s":{"default-cpus":"100m","default-env-vars":[{"FLYTE_AWS_ENDPOINT":"http://minio.flyte:9000"},{"FLYTE_AWS_ACCESS_KEY_ID":"minio"},{"FLYTE_AWS_SECRET_ACCESS_KEY":"miniostorage"}],"default-memory":"200Mi"}}},"logger":{"logger":{"level":5,"show-source":true}},"remoteData":{"remoteData":{"region":"us-east-1","scheme":"local","signedUrls":{"durationMinutes":3}}},"resource_manager":{"propeller":{"resourcemanager":{"redis":null,"type":"noop"}}},"task_logs":{"plugins":{"logs":{"cloudwatch-enabled":false,"kubernetes-enabled":true,"kubernetes-template-uri":"http://localhost:30082/#/log/{{ \"{{\" }} .namespace {{ \"}}\" }}/{{ \"{{\" }} .podName {{ \"}}\" }}/pod?namespace={{ \"{{\" }} .namespace {{ \"}}\" }}"}}},"task_resource_defaults":{"task_resources":{"defaults":{"cpu":"100m","memory":"200Mi","storage":"5Mi"},"limits":{"cpu":2,"gpu":1,"memory":"1Gi","storage":"20Mi"}}}}` | ----------------------------------------------------------------- CONFIGMAPS SETTINGS | +| flyte.configmap | object | `{"adminServer":{"auth":{"appAuth":{"thirdPartyConfig":{"flyteClient":{"clientId":"flytectl","redirectUri":"http://localhost:53593/callback","scopes":["offline","all"]}}},"authorizedUris":["https://localhost:30081","http://flyteadmin:80","http://flyteadmin.flyte.svc.cluster.local:80"],"userAuth":{"openId":{"baseUrl":"https://accounts.google.com","clientId":"657465813211-6eog7ek7li5k7i7fvgv2921075063hpe.apps.googleusercontent.com","scopes":["profile","openid"]}}},"flyteadmin":{"eventVersion":2,"metadataStoragePrefix":["metadata","admin"],"metricsScope":"flyte:","profilerPort":10254,"roleNameKey":"iam.amazonaws.com/role","testing":{"host":"http://flyteadmin"}},"server":{"grpcPort":8089,"httpPort":8088,"security":{"allowCors":true,"allowedHeaders":["Content-Type","flyte-authorization"],"allowedOrigins":["*"],"secure":false,"useAuth":false}}},"catalog":{"catalog-cache":{"endpoint":"datacatalog:89","insecure":true,"type":"datacatalog"}},"console":{"BASE_URL":"/console","CONFIG_DIR":"/etc/flyte/config"},"copilot":{"plugins":{"k8s":{"co-pilot":{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6","name":"flyte-copilot-","start-timeout":"30s"}}}},"core":{"propeller":{"downstream-eval-duration":"30s","enable-admin-launcher":true,"leader-election":{"enabled":true,"lease-duration":"15s","lock-config-map":{"name":"propeller-leader","namespace":"flyte"},"renew-deadline":"10s","retry-period":"2s"},"limit-namespace":"all","max-workflow-retries":30,"metadata-prefix":"metadata/propeller","metrics-prefix":"flyte","prof-port":10254,"queue":{"batch-size":-1,"batching-interval":"2s","queue":{"base-delay":"5s","capacity":1000,"max-delay":"120s","rate":100,"type":"maxof"},"sub-queue":{"capacity":100,"rate":10,"type":"bucket"},"type":"batch"},"rawoutput-prefix":"s3://my-s3-bucket/","workers":4,"workflow-reeval-duration":"30s"},"webhook":{"certDir":"/etc/webhook/certs","serviceName":"flyte-pod-webhook"}},"datacatalogServer":{"application":{"grpcPort":8089,"grpcServerReflection":true,"httpPort":8080},"datacatalog":{"metrics-scope":"datacatalog","profiler-port":10254,"storage-prefix":"metadata/datacatalog"}},"domain":{"domains":[{"id":"development","name":"development"},{"id":"staging","name":"staging"},{"id":"production","name":"production"}]},"enabled_plugins":{"tasks":{"task-plugins":{"default-for-task-types":{"bigquery_query_job_task":"agent-service","container":"container","container_array":"k8s-array","sidecar":"sidecar"},"enabled-plugins":["container","sidecar","k8s-array","agent-service"]}}},"k8s":{"plugins":{"agent-service":{"defaultAgent":{"endpoint":"dns:///flyteagent.flyte.svc.cluster.local:8000","insecure":true},"supportedTaskTypes":["bigquery_query_job_task"]},"k8s":{"default-cpus":"100m","default-env-vars":[{"FLYTE_AWS_ENDPOINT":"http://minio.flyte:9000"},{"FLYTE_AWS_ACCESS_KEY_ID":"minio"},{"FLYTE_AWS_SECRET_ACCESS_KEY":"miniostorage"}],"default-memory":"200Mi"}}},"logger":{"logger":{"level":5,"show-source":true}},"remoteData":{"remoteData":{"region":"us-east-1","scheme":"local","signedUrls":{"durationMinutes":3}}},"resource_manager":{"propeller":{"resourcemanager":{"redis":null,"type":"noop"}}},"task_logs":{"plugins":{"logs":{"cloudwatch-enabled":false,"kubernetes-enabled":true,"kubernetes-template-uri":"http://localhost:30082/#/log/{{ \"{{\" }} .namespace {{ \"}}\" }}/{{ \"{{\" }} .podName {{ \"}}\" }}/pod?namespace={{ \"{{\" }} .namespace {{ \"}}\" }}"}}},"task_resource_defaults":{"task_resources":{"defaults":{"cpu":"100m","memory":"200Mi","storage":"5Mi"},"limits":{"cpu":2,"gpu":1,"memory":"1Gi","storage":"20Mi"}}}}` | ----------------------------------------------------------------- CONFIGMAPS SETTINGS | | flyte.configmap.adminServer | object | `{"auth":{"appAuth":{"thirdPartyConfig":{"flyteClient":{"clientId":"flytectl","redirectUri":"http://localhost:53593/callback","scopes":["offline","all"]}}},"authorizedUris":["https://localhost:30081","http://flyteadmin:80","http://flyteadmin.flyte.svc.cluster.local:80"],"userAuth":{"openId":{"baseUrl":"https://accounts.google.com","clientId":"657465813211-6eog7ek7li5k7i7fvgv2921075063hpe.apps.googleusercontent.com","scopes":["profile","openid"]}}},"flyteadmin":{"eventVersion":2,"metadataStoragePrefix":["metadata","admin"],"metricsScope":"flyte:","profilerPort":10254,"roleNameKey":"iam.amazonaws.com/role","testing":{"host":"http://flyteadmin"}},"server":{"grpcPort":8089,"httpPort":8088,"security":{"allowCors":true,"allowedHeaders":["Content-Type","flyte-authorization"],"allowedOrigins":["*"],"secure":false,"useAuth":false}}}` | FlyteAdmin server configuration | | flyte.configmap.adminServer.auth | object | `{"appAuth":{"thirdPartyConfig":{"flyteClient":{"clientId":"flytectl","redirectUri":"http://localhost:53593/callback","scopes":["offline","all"]}}},"authorizedUris":["https://localhost:30081","http://flyteadmin:80","http://flyteadmin.flyte.svc.cluster.local:80"],"userAuth":{"openId":{"baseUrl":"https://accounts.google.com","clientId":"657465813211-6eog7ek7li5k7i7fvgv2921075063hpe.apps.googleusercontent.com","scopes":["profile","openid"]}}}` | Authentication configuration | | flyte.configmap.adminServer.server.security.secure | bool | `false` | Controls whether to serve requests over SSL/TLS. | | flyte.configmap.adminServer.server.security.useAuth | bool | `false` | Controls whether to enforce authentication. Follow the guide in https://docs.flyte.org/ on how to setup authentication. | | flyte.configmap.catalog | object | `{"catalog-cache":{"endpoint":"datacatalog:89","insecure":true,"type":"datacatalog"}}` | Catalog Client configuration [structure](https://pkg.go.dev/github.com/flyteorg/flytepropeller/pkg/controller/nodes/task/catalog#Config) Additional advanced Catalog configuration [here](https://pkg.go.dev/github.com/lyft/flyteplugins/go/tasks/pluginmachinery/catalog#Config) | | flyte.configmap.console | object | `{"BASE_URL":"/console","CONFIG_DIR":"/etc/flyte/config"}` | Configuration for Flyte console UI | -| flyte.configmap.copilot | object | `{"plugins":{"k8s":{"co-pilot":{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0","name":"flyte-copilot-","start-timeout":"30s"}}}}` | Copilot configuration | -| flyte.configmap.copilot.plugins.k8s.co-pilot | object | `{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0","name":"flyte-copilot-","start-timeout":"30s"}` | Structure documented [here](https://pkg.go.dev/github.com/lyft/flyteplugins@v0.5.28/go/tasks/pluginmachinery/flytek8s/config#FlyteCoPilotConfig) | +| flyte.configmap.copilot | object | `{"plugins":{"k8s":{"co-pilot":{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6","name":"flyte-copilot-","start-timeout":"30s"}}}}` | Copilot configuration | +| flyte.configmap.copilot.plugins.k8s.co-pilot | object | `{"image":"cr.flyte.org/flyteorg/flytecopilot:v1.10.6","name":"flyte-copilot-","start-timeout":"30s"}` | Structure documented [here](https://pkg.go.dev/github.com/lyft/flyteplugins@v0.5.28/go/tasks/pluginmachinery/flytek8s/config#FlyteCoPilotConfig) | | flyte.configmap.core | object | `{"propeller":{"downstream-eval-duration":"30s","enable-admin-launcher":true,"leader-election":{"enabled":true,"lease-duration":"15s","lock-config-map":{"name":"propeller-leader","namespace":"flyte"},"renew-deadline":"10s","retry-period":"2s"},"limit-namespace":"all","max-workflow-retries":30,"metadata-prefix":"metadata/propeller","metrics-prefix":"flyte","prof-port":10254,"queue":{"batch-size":-1,"batching-interval":"2s","queue":{"base-delay":"5s","capacity":1000,"max-delay":"120s","rate":100,"type":"maxof"},"sub-queue":{"capacity":100,"rate":10,"type":"bucket"},"type":"batch"},"rawoutput-prefix":"s3://my-s3-bucket/","workers":4,"workflow-reeval-duration":"30s"},"webhook":{"certDir":"/etc/webhook/certs","serviceName":"flyte-pod-webhook"}}` | Core propeller configuration | | flyte.configmap.core.propeller | object | `{"downstream-eval-duration":"30s","enable-admin-launcher":true,"leader-election":{"enabled":true,"lease-duration":"15s","lock-config-map":{"name":"propeller-leader","namespace":"flyte"},"renew-deadline":"10s","retry-period":"2s"},"limit-namespace":"all","max-workflow-retries":30,"metadata-prefix":"metadata/propeller","metrics-prefix":"flyte","prof-port":10254,"queue":{"batch-size":-1,"batching-interval":"2s","queue":{"base-delay":"5s","capacity":1000,"max-delay":"120s","rate":100,"type":"maxof"},"sub-queue":{"capacity":100,"rate":10,"type":"bucket"},"type":"batch"},"rawoutput-prefix":"s3://my-s3-bucket/","workers":4,"workflow-reeval-duration":"30s"}` | follows the structure specified [here](https://pkg.go.dev/github.com/flyteorg/flytepropeller/pkg/controller/config). | | flyte.configmap.datacatalogServer | object | `{"application":{"grpcPort":8089,"grpcServerReflection":true,"httpPort":8080},"datacatalog":{"metrics-scope":"datacatalog","profiler-port":10254,"storage-prefix":"metadata/datacatalog"}}` | Datacatalog server config | @@ -120,7 +120,7 @@ helm upgrade -f values-sandbox.yaml flyte . | flyte.datacatalog.configPath | string | `"/etc/datacatalog/config/*.yaml"` | Default regex string for searching configuration files | | flyte.datacatalog.image.pullPolicy | string | `"IfNotPresent"` | Docker image pull policy | | flyte.datacatalog.image.repository | string | `"cr.flyte.org/flyteorg/datacatalog"` | Docker image for Datacatalog deployment | -| flyte.datacatalog.image.tag | string | `"v1.10.6-b0"` | Docker image tag | +| flyte.datacatalog.image.tag | string | `"v1.10.6"` | Docker image tag | | flyte.datacatalog.nodeSelector | object | `{}` | nodeSelector for Datacatalog deployment | | flyte.datacatalog.podAnnotations | object | `{}` | Annotations for Datacatalog pods | | flyte.datacatalog.replicaCount | int | `1` | Replicas count for Datacatalog deployment | @@ -136,7 +136,7 @@ helm upgrade -f values-sandbox.yaml flyte . | flyte.flyteadmin.env | list | `[]` | Additional flyteadmin container environment variables e.g. SendGrid's API key - name: SENDGRID_API_KEY value: "" e.g. secret environment variable (you can combine it with .additionalVolumes): - name: SENDGRID_API_KEY valueFrom: secretKeyRef: name: sendgrid-secret key: api_key | | flyte.flyteadmin.image.pullPolicy | string | `"IfNotPresent"` | Docker image pull policy | | flyte.flyteadmin.image.repository | string | `"cr.flyte.org/flyteorg/flyteadmin"` | Docker image for Flyteadmin deployment | -| flyte.flyteadmin.image.tag | string | `"v1.10.6-b0"` | Docker image tag | +| flyte.flyteadmin.image.tag | string | `"v1.10.6"` | Docker image tag | | flyte.flyteadmin.initialProjects | list | `["flytesnacks","flytetester","flyteexamples"]` | Initial projects to create | | flyte.flyteadmin.nodeSelector | object | `{}` | nodeSelector for Flyteadmin deployment | | flyte.flyteadmin.podAnnotations | object | `{}` | Annotations for Flyteadmin pods | @@ -162,7 +162,7 @@ helm upgrade -f values-sandbox.yaml flyte . | flyte.flytepropeller.configPath | string | `"/etc/flyte/config/*.yaml"` | Default regex string for searching configuration files | | flyte.flytepropeller.image.pullPolicy | string | `"IfNotPresent"` | Docker image pull policy | | flyte.flytepropeller.image.repository | string | `"cr.flyte.org/flyteorg/flytepropeller"` | Docker image for Flytepropeller deployment | -| flyte.flytepropeller.image.tag | string | `"v1.10.6-b0"` | Docker image tag | +| flyte.flytepropeller.image.tag | string | `"v1.10.6"` | Docker image tag | | flyte.flytepropeller.nodeSelector | object | `{}` | nodeSelector for Flytepropeller deployment | | flyte.flytepropeller.podAnnotations | object | `{}` | Annotations for Flytepropeller pods | | flyte.flytepropeller.replicaCount | int | `1` | Replicas count for Flytepropeller deployment | @@ -176,7 +176,7 @@ helm upgrade -f values-sandbox.yaml flyte . | flyte.flytescheduler.configPath | string | `"/etc/flyte/config/*.yaml"` | Default regex string for searching configuration files | | flyte.flytescheduler.image.pullPolicy | string | `"IfNotPresent"` | Docker image pull policy | | flyte.flytescheduler.image.repository | string | `"cr.flyte.org/flyteorg/flytescheduler"` | Docker image for Flytescheduler deployment | -| flyte.flytescheduler.image.tag | string | `"v1.10.6-b0"` | Docker image tag | +| flyte.flytescheduler.image.tag | string | `"v1.10.6"` | Docker image tag | | flyte.flytescheduler.nodeSelector | object | `{}` | nodeSelector for Flytescheduler deployment | | flyte.flytescheduler.podAnnotations | object | `{}` | Annotations for Flytescheduler pods | | flyte.flytescheduler.resources | object | `{"limits":{"cpu":"250m","ephemeral-storage":"100Mi","memory":"500Mi"},"requests":{"cpu":"10m","ephemeral-storage":"50Mi","memory":"50Mi"}}` | Default resources requests and limits for Flytescheduler deployment | diff --git a/charts/flyte/values.yaml b/charts/flyte/values.yaml index 9ed3786c27..36d2a440db 100755 --- a/charts/flyte/values.yaml +++ b/charts/flyte/values.yaml @@ -16,7 +16,7 @@ flyte: # -- Docker image for Flyteadmin deployment repository: cr.flyte.org/flyteorg/flyteadmin # FLYTEADMIN_IMAGE # -- Docker image tag - tag: v1.10.6-b0 # FLYTEADMIN_TAG + tag: v1.10.6 # FLYTEADMIN_TAG # -- Docker image pull policy pullPolicy: IfNotPresent # -- Additional flyteadmin container environment variables @@ -84,7 +84,7 @@ flyte: # -- Docker image for Flytescheduler deployment repository: cr.flyte.org/flyteorg/flytescheduler # FLYTESCHEDULER_IMAGE # -- Docker image tag - tag: v1.10.6-b0 # FLYTESCHEDULER_TAG + tag: v1.10.6 # FLYTESCHEDULER_TAG # -- Docker image pull policy pullPolicy: IfNotPresent # -- Default resources requests and limits for Flytescheduler deployment @@ -129,7 +129,7 @@ flyte: # -- Docker image for Datacatalog deployment repository: cr.flyte.org/flyteorg/datacatalog # DATACATALOG_IMAGE # -- Docker image tag - tag: v1.10.6-b0 # DATACATALOG_TAG + tag: v1.10.6 # DATACATALOG_TAG # -- Docker image pull policy pullPolicy: IfNotPresent # -- Default resources requests and limits for Datacatalog deployment @@ -178,7 +178,7 @@ flyte: # -- Docker image for Flytepropeller deployment repository: cr.flyte.org/flyteorg/flytepropeller # FLYTEPROPELLER_IMAGE # -- Docker image tag - tag: v1.10.6-b0 # FLYTEPROPELLER_TAG + tag: v1.10.6 # FLYTEPROPELLER_TAG # -- Docker image pull policy pullPolicy: IfNotPresent # -- Default resources requests and limits for Flytepropeller deployment @@ -471,7 +471,7 @@ flyte: # -- Structure documented [here](https://pkg.go.dev/github.com/lyft/flyteplugins@v0.5.28/go/tasks/pluginmachinery/flytek8s/config#FlyteCoPilotConfig) co-pilot: name: flyte-copilot- - image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0 # FLYTECOPILOT_IMAGE + image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6 # FLYTECOPILOT_IMAGE start-timeout: 30s # -- Core propeller configuration diff --git a/deployment/eks/flyte_aws_scheduler_helm_generated.yaml b/deployment/eks/flyte_aws_scheduler_helm_generated.yaml index 6486d4ef7f..647754edda 100644 --- a/deployment/eks/flyte_aws_scheduler_helm_generated.yaml +++ b/deployment/eks/flyte_aws_scheduler_helm_generated.yaml @@ -429,7 +429,7 @@ data: plugins: k8s: co-pilot: - image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6 name: flyte-copilot- start-timeout: 30s core.yaml: | @@ -865,7 +865,7 @@ spec: - /etc/flyte/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -882,7 +882,7 @@ spec: - flytesnacks - flytetester - flyteexamples - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: seed-projects volumeMounts: @@ -896,7 +896,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -909,7 +909,7 @@ spec: - mountPath: /etc/secrets/ name: admin-secrets - name: generate-secrets - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" command: ["/bin/sh", "-c"] args: @@ -932,7 +932,7 @@ spec: - --config - /etc/flyte/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: flyteadmin ports: @@ -1033,7 +1033,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -1153,7 +1153,7 @@ spec: - /etc/datacatalog/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -1167,7 +1167,7 @@ spec: - --config - /etc/datacatalog/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: datacatalog ports: @@ -1226,7 +1226,7 @@ spec: template: metadata: annotations: - configChecksum: "01088dc304d9857ab4f20c70a1051db600696c081ac978e44304725430899d8" + configChecksum: "fd3294c2987d4c2863e13a84abd65a284f69332d97a698c833c27e5c9f5417a" labels: app.kubernetes.io/name: flytepropeller app.kubernetes.io/instance: flyte @@ -1252,7 +1252,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytepropeller ports: @@ -1306,9 +1306,9 @@ spec: labels: app: flyte-pod-webhook app.kubernetes.io/name: flyte-pod-webhook - app.kubernetes.io/version: v1.10.6-b0 + app.kubernetes.io/version: v1.10.6 annotations: - configChecksum: "01088dc304d9857ab4f20c70a1051db600696c081ac978e44304725430899d8" + configChecksum: "fd3294c2987d4c2863e13a84abd65a284f69332d97a698c833c27e5c9f5417a" spec: securityContext: fsGroup: 65534 @@ -1317,7 +1317,7 @@ spec: serviceAccountName: flyte-pod-webhook initContainers: - name: generate-secrets - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller @@ -1340,7 +1340,7 @@ spec: mountPath: /etc/flyte/config containers: - name: webhook - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller diff --git a/deployment/eks/flyte_generated.yaml b/deployment/eks/flyte_generated.yaml index ce834b3639..5729fea0e2 100644 --- a/deployment/eks/flyte_generated.yaml +++ b/deployment/eks/flyte_generated.yaml @@ -8640,7 +8640,7 @@ spec: - --config - /etc/datacatalog/config/*.yaml - serve - image: cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0 + image: cr.flyte.org/flyteorg/datacatalog:v1.10.6 imagePullPolicy: IfNotPresent name: datacatalog ports: @@ -8663,7 +8663,7 @@ spec: - /etc/datacatalog/config/*.yaml - migrate - run - image: cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0 + image: cr.flyte.org/flyteorg/datacatalog:v1.10.6 imagePullPolicy: IfNotPresent name: run-migrations volumeMounts: @@ -8724,7 +8724,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flytepropeller:v1.10.6 imagePullPolicy: IfNotPresent name: webhook volumeMounts: @@ -8751,7 +8751,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flytepropeller:v1.10.6 imagePullPolicy: IfNotPresent name: generate-secrets volumeMounts: @@ -8799,7 +8799,7 @@ spec: - --config - /etc/flyte/config/*.yaml - serve - image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6 imagePullPolicy: IfNotPresent name: flyteadmin ports: @@ -8846,7 +8846,7 @@ spec: - /etc/flyte/config/*.yaml - migrate - run - image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6 imagePullPolicy: IfNotPresent name: run-migrations volumeMounts: @@ -8863,7 +8863,7 @@ spec: - flytesnacks - flytetester - flyteexamples - image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6 imagePullPolicy: IfNotPresent name: seed-projects volumeMounts: @@ -8877,7 +8877,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6 imagePullPolicy: IfNotPresent name: sync-cluster-resources volumeMounts: @@ -8897,7 +8897,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6 imagePullPolicy: IfNotPresent name: generate-secrets volumeMounts: @@ -9002,7 +9002,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flytepropeller:v1.10.6 imagePullPolicy: IfNotPresent name: flytepropeller ports: @@ -9270,7 +9270,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flyteadmin:v1.10.6 imagePullPolicy: IfNotPresent name: sync-cluster-resources volumeMounts: diff --git a/deployment/eks/flyte_helm_controlplane_generated.yaml b/deployment/eks/flyte_helm_controlplane_generated.yaml index 1b16c7db6a..30a03b4498 100644 --- a/deployment/eks/flyte_helm_controlplane_generated.yaml +++ b/deployment/eks/flyte_helm_controlplane_generated.yaml @@ -571,7 +571,7 @@ spec: - /etc/flyte/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -588,7 +588,7 @@ spec: - flytesnacks - flytetester - flyteexamples - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: seed-projects volumeMounts: @@ -602,7 +602,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -615,7 +615,7 @@ spec: - mountPath: /etc/secrets/ name: admin-secrets - name: generate-secrets - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" command: ["/bin/sh", "-c"] args: @@ -638,7 +638,7 @@ spec: - --config - /etc/flyte/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: flyteadmin ports: @@ -739,7 +739,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -859,7 +859,7 @@ spec: - /etc/datacatalog/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -873,7 +873,7 @@ spec: - --config - /etc/datacatalog/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: datacatalog ports: @@ -949,7 +949,7 @@ spec: - precheck - --config - /etc/flyte/config/*.yaml - image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytescheduler-check volumeMounts: @@ -965,7 +965,7 @@ spec: - run - --config - /etc/flyte/config/*.yaml - image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytescheduler ports: diff --git a/deployment/eks/flyte_helm_dataplane_generated.yaml b/deployment/eks/flyte_helm_dataplane_generated.yaml index e10142c57f..e5655a4c53 100644 --- a/deployment/eks/flyte_helm_dataplane_generated.yaml +++ b/deployment/eks/flyte_helm_dataplane_generated.yaml @@ -94,7 +94,7 @@ data: plugins: k8s: co-pilot: - image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6 name: flyte-copilot- start-timeout: 30s core.yaml: | @@ -427,7 +427,7 @@ spec: template: metadata: annotations: - configChecksum: "01088dc304d9857ab4f20c70a1051db600696c081ac978e44304725430899d8" + configChecksum: "fd3294c2987d4c2863e13a84abd65a284f69332d97a698c833c27e5c9f5417a" labels: app.kubernetes.io/name: flytepropeller app.kubernetes.io/instance: flyte @@ -453,7 +453,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytepropeller ports: @@ -507,9 +507,9 @@ spec: labels: app: flyte-pod-webhook app.kubernetes.io/name: flyte-pod-webhook - app.kubernetes.io/version: v1.10.6-b0 + app.kubernetes.io/version: v1.10.6 annotations: - configChecksum: "01088dc304d9857ab4f20c70a1051db600696c081ac978e44304725430899d8" + configChecksum: "fd3294c2987d4c2863e13a84abd65a284f69332d97a698c833c27e5c9f5417a" spec: securityContext: fsGroup: 65534 @@ -518,7 +518,7 @@ spec: serviceAccountName: flyte-pod-webhook initContainers: - name: generate-secrets - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller @@ -541,7 +541,7 @@ spec: mountPath: /etc/flyte/config containers: - name: webhook - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller diff --git a/deployment/eks/flyte_helm_generated.yaml b/deployment/eks/flyte_helm_generated.yaml index 6214f2aa6e..45fed80156 100644 --- a/deployment/eks/flyte_helm_generated.yaml +++ b/deployment/eks/flyte_helm_generated.yaml @@ -460,7 +460,7 @@ data: plugins: k8s: co-pilot: - image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6 name: flyte-copilot- start-timeout: 30s core.yaml: | @@ -896,7 +896,7 @@ spec: - /etc/flyte/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -913,7 +913,7 @@ spec: - flytesnacks - flytetester - flyteexamples - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: seed-projects volumeMounts: @@ -927,7 +927,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -940,7 +940,7 @@ spec: - mountPath: /etc/secrets/ name: admin-secrets - name: generate-secrets - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" command: ["/bin/sh", "-c"] args: @@ -963,7 +963,7 @@ spec: - --config - /etc/flyte/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: flyteadmin ports: @@ -1064,7 +1064,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -1184,7 +1184,7 @@ spec: - /etc/datacatalog/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -1198,7 +1198,7 @@ spec: - --config - /etc/datacatalog/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: datacatalog ports: @@ -1274,7 +1274,7 @@ spec: - precheck - --config - /etc/flyte/config/*.yaml - image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytescheduler-check volumeMounts: @@ -1290,7 +1290,7 @@ spec: - run - --config - /etc/flyte/config/*.yaml - image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytescheduler ports: @@ -1345,7 +1345,7 @@ spec: template: metadata: annotations: - configChecksum: "01088dc304d9857ab4f20c70a1051db600696c081ac978e44304725430899d8" + configChecksum: "fd3294c2987d4c2863e13a84abd65a284f69332d97a698c833c27e5c9f5417a" labels: app.kubernetes.io/name: flytepropeller app.kubernetes.io/instance: flyte @@ -1371,7 +1371,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytepropeller ports: @@ -1425,9 +1425,9 @@ spec: labels: app: flyte-pod-webhook app.kubernetes.io/name: flyte-pod-webhook - app.kubernetes.io/version: v1.10.6-b0 + app.kubernetes.io/version: v1.10.6 annotations: - configChecksum: "01088dc304d9857ab4f20c70a1051db600696c081ac978e44304725430899d8" + configChecksum: "fd3294c2987d4c2863e13a84abd65a284f69332d97a698c833c27e5c9f5417a" spec: securityContext: fsGroup: 65534 @@ -1436,7 +1436,7 @@ spec: serviceAccountName: flyte-pod-webhook initContainers: - name: generate-secrets - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller @@ -1459,7 +1459,7 @@ spec: mountPath: /etc/flyte/config containers: - name: webhook - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller diff --git a/deployment/gcp/flyte_helm_controlplane_generated.yaml b/deployment/gcp/flyte_helm_controlplane_generated.yaml index 118a933a1c..29be77bd52 100644 --- a/deployment/gcp/flyte_helm_controlplane_generated.yaml +++ b/deployment/gcp/flyte_helm_controlplane_generated.yaml @@ -586,7 +586,7 @@ spec: - /etc/flyte/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -603,7 +603,7 @@ spec: - flytesnacks - flytetester - flyteexamples - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: seed-projects volumeMounts: @@ -617,7 +617,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -630,7 +630,7 @@ spec: - mountPath: /etc/secrets/ name: admin-secrets - name: generate-secrets - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" command: ["/bin/sh", "-c"] args: @@ -653,7 +653,7 @@ spec: - --config - /etc/flyte/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: flyteadmin ports: @@ -754,7 +754,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -874,7 +874,7 @@ spec: - /etc/datacatalog/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -888,7 +888,7 @@ spec: - --config - /etc/datacatalog/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: datacatalog ports: @@ -964,7 +964,7 @@ spec: - precheck - --config - /etc/flyte/config/*.yaml - image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytescheduler-check volumeMounts: @@ -980,7 +980,7 @@ spec: - run - --config - /etc/flyte/config/*.yaml - image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytescheduler ports: diff --git a/deployment/gcp/flyte_helm_dataplane_generated.yaml b/deployment/gcp/flyte_helm_dataplane_generated.yaml index d97cb4f539..bfe7b45516 100644 --- a/deployment/gcp/flyte_helm_dataplane_generated.yaml +++ b/deployment/gcp/flyte_helm_dataplane_generated.yaml @@ -94,7 +94,7 @@ data: plugins: k8s: co-pilot: - image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6 name: flyte-copilot- start-timeout: 30s core.yaml: | @@ -435,7 +435,7 @@ spec: template: metadata: annotations: - configChecksum: "1807fcd06e7ba88ec8324c5d335d66b159dc028aecae528214f15a119440e25" + configChecksum: "5cfa27fed34037ee9e992af31d950a82a9abe1e77f10b7bd7f37d2fb6b935e1" labels: app.kubernetes.io/name: flytepropeller app.kubernetes.io/instance: flyte @@ -460,7 +460,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytepropeller ports: @@ -514,9 +514,9 @@ spec: labels: app: flyte-pod-webhook app.kubernetes.io/name: flyte-pod-webhook - app.kubernetes.io/version: v1.10.6-b0 + app.kubernetes.io/version: v1.10.6 annotations: - configChecksum: "1807fcd06e7ba88ec8324c5d335d66b159dc028aecae528214f15a119440e25" + configChecksum: "5cfa27fed34037ee9e992af31d950a82a9abe1e77f10b7bd7f37d2fb6b935e1" spec: securityContext: fsGroup: 65534 @@ -525,7 +525,7 @@ spec: serviceAccountName: flyte-pod-webhook initContainers: - name: generate-secrets - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller @@ -548,7 +548,7 @@ spec: mountPath: /etc/flyte/config containers: - name: webhook - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller diff --git a/deployment/gcp/flyte_helm_generated.yaml b/deployment/gcp/flyte_helm_generated.yaml index 8ec2e2817f..9c81b402c5 100644 --- a/deployment/gcp/flyte_helm_generated.yaml +++ b/deployment/gcp/flyte_helm_generated.yaml @@ -473,7 +473,7 @@ data: plugins: k8s: co-pilot: - image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6 name: flyte-copilot- start-timeout: 30s core.yaml: | @@ -919,7 +919,7 @@ spec: - /etc/flyte/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -936,7 +936,7 @@ spec: - flytesnacks - flytetester - flyteexamples - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: seed-projects volumeMounts: @@ -950,7 +950,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -963,7 +963,7 @@ spec: - mountPath: /etc/secrets/ name: admin-secrets - name: generate-secrets - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" command: ["/bin/sh", "-c"] args: @@ -986,7 +986,7 @@ spec: - --config - /etc/flyte/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: flyteadmin ports: @@ -1087,7 +1087,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -1207,7 +1207,7 @@ spec: - /etc/datacatalog/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -1221,7 +1221,7 @@ spec: - --config - /etc/datacatalog/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: datacatalog ports: @@ -1297,7 +1297,7 @@ spec: - precheck - --config - /etc/flyte/config/*.yaml - image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytescheduler-check volumeMounts: @@ -1313,7 +1313,7 @@ spec: - run - --config - /etc/flyte/config/*.yaml - image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytescheduler ports: @@ -1368,7 +1368,7 @@ spec: template: metadata: annotations: - configChecksum: "1807fcd06e7ba88ec8324c5d335d66b159dc028aecae528214f15a119440e25" + configChecksum: "5cfa27fed34037ee9e992af31d950a82a9abe1e77f10b7bd7f37d2fb6b935e1" labels: app.kubernetes.io/name: flytepropeller app.kubernetes.io/instance: flyte @@ -1393,7 +1393,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytepropeller ports: @@ -1447,9 +1447,9 @@ spec: labels: app: flyte-pod-webhook app.kubernetes.io/name: flyte-pod-webhook - app.kubernetes.io/version: v1.10.6-b0 + app.kubernetes.io/version: v1.10.6 annotations: - configChecksum: "1807fcd06e7ba88ec8324c5d335d66b159dc028aecae528214f15a119440e25" + configChecksum: "5cfa27fed34037ee9e992af31d950a82a9abe1e77f10b7bd7f37d2fb6b935e1" spec: securityContext: fsGroup: 65534 @@ -1458,7 +1458,7 @@ spec: serviceAccountName: flyte-pod-webhook initContainers: - name: generate-secrets - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller @@ -1481,7 +1481,7 @@ spec: mountPath: /etc/flyte/config containers: - name: webhook - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller diff --git a/deployment/sandbox-binary/flyte_sandbox_binary_helm_generated.yaml b/deployment/sandbox-binary/flyte_sandbox_binary_helm_generated.yaml index 220646a806..2e667f1256 100644 --- a/deployment/sandbox-binary/flyte_sandbox_binary_helm_generated.yaml +++ b/deployment/sandbox-binary/flyte_sandbox_binary_helm_generated.yaml @@ -116,7 +116,7 @@ data: stackdriver-enabled: false k8s: co-pilot: - image: "cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytecopilot:v1.10.6" k8s-array: logs: config: @@ -367,7 +367,7 @@ spec: app.kubernetes.io/instance: flyte app.kubernetes.io/component: flyte-binary annotations: - checksum/configuration: d36a779520b6a2f4e13493db137c2d4022382d282b0e4a3845c07c2f6e49c3b0 + checksum/configuration: 51494d8c2f3a6df2711d789217155f1e1b60e782dcbfd4564bfcccda24700576 checksum/configuration-secret: d5d93f4e67780b21593dc3799f0f6682aab0765e708e4020939975d14d44f929 checksum/cluster-resource-templates: 7dfa59f3d447e9c099b8f8ffad3af466fecbc9cf9f8c97295d9634254a55d4ae spec: diff --git a/deployment/sandbox/flyte_helm_generated.yaml b/deployment/sandbox/flyte_helm_generated.yaml index f2e7314632..26a61908ed 100644 --- a/deployment/sandbox/flyte_helm_generated.yaml +++ b/deployment/sandbox/flyte_helm_generated.yaml @@ -585,7 +585,7 @@ data: plugins: k8s: co-pilot: - image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0 + image: cr.flyte.org/flyteorg/flytecopilot:v1.10.6 name: flyte-copilot- start-timeout: 30s core.yaml: | @@ -6708,7 +6708,7 @@ spec: - /etc/flyte/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -6724,7 +6724,7 @@ spec: - flytesnacks - flytetester - flyteexamples - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: seed-projects volumeMounts: @@ -6737,7 +6737,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -6749,7 +6749,7 @@ spec: - mountPath: /etc/secrets/ name: admin-secrets - name: generate-secrets - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" command: ["/bin/sh", "-c"] args: @@ -6772,7 +6772,7 @@ spec: - --config - /etc/flyte/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: flyteadmin ports: @@ -6863,7 +6863,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - run - image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flyteadmin:v1.10.6" imagePullPolicy: "IfNotPresent" name: sync-cluster-resources volumeMounts: @@ -6978,7 +6978,7 @@ spec: - /etc/datacatalog/config/*.yaml - migrate - run - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: run-migrations volumeMounts: @@ -6991,7 +6991,7 @@ spec: - --config - /etc/datacatalog/config/*.yaml - serve - image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/datacatalog:v1.10.6" imagePullPolicy: "IfNotPresent" name: datacatalog ports: @@ -7057,7 +7057,7 @@ spec: - precheck - --config - /etc/flyte/config/*.yaml - image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytescheduler-check volumeMounts: @@ -7072,7 +7072,7 @@ spec: - run - --config - /etc/flyte/config/*.yaml - image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytescheduler:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytescheduler ports: @@ -7124,7 +7124,7 @@ spec: template: metadata: annotations: - configChecksum: "a81a5fa25d21cbff03e67eadb8829e2d51cb9e1bc4ae540c4186c717f971d36" + configChecksum: "3d2a38f6286a81fa144d0690a97cf10282a73e862a2a3b5a3e0bb2911aac9ca" labels: app.kubernetes.io/name: flytepropeller app.kubernetes.io/instance: flyte @@ -7149,7 +7149,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" name: flytepropeller ports: @@ -7196,9 +7196,9 @@ spec: labels: app: flyte-pod-webhook app.kubernetes.io/name: flyte-pod-webhook - app.kubernetes.io/version: v1.10.6-b0 + app.kubernetes.io/version: v1.10.6 annotations: - configChecksum: "a81a5fa25d21cbff03e67eadb8829e2d51cb9e1bc4ae540c4186c717f971d36" + configChecksum: "3d2a38f6286a81fa144d0690a97cf10282a73e862a2a3b5a3e0bb2911aac9ca" spec: securityContext: fsGroup: 65534 @@ -7207,7 +7207,7 @@ spec: serviceAccountName: flyte-pod-webhook initContainers: - name: generate-secrets - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller @@ -7230,7 +7230,7 @@ spec: mountPath: /etc/flyte/config containers: - name: webhook - image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytepropeller:v1.10.6" imagePullPolicy: "IfNotPresent" command: - flytepropeller diff --git a/docker/sandbox-bundled/manifests/complete-agent.yaml b/docker/sandbox-bundled/manifests/complete-agent.yaml index ac4112b408..4380b96277 100644 --- a/docker/sandbox-bundled/manifests/complete-agent.yaml +++ b/docker/sandbox-bundled/manifests/complete-agent.yaml @@ -468,7 +468,7 @@ data: stackdriver-enabled: false k8s: co-pilot: - image: "cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytecopilot:v1.10.6" k8s-array: logs: config: @@ -816,7 +816,7 @@ type: Opaque --- apiVersion: v1 data: - haSharedSecret: cXJOakphaFFlOVVTNzdMTw== + haSharedSecret: ZnNFaHlpM01FZjRaQmNJSA== proxyPassword: "" proxyUsername: "" kind: Secret @@ -1246,7 +1246,7 @@ spec: metadata: annotations: checksum/cluster-resource-templates: 6fd9b172465e3089fcc59f738b92b8dc4d8939360c19de8ee65f68b0e7422035 - checksum/configuration: 832fc20170bd24c5262c6b6a741066a2cfa308183e3adb60810396bfbe85a750 + checksum/configuration: 6755bdc74789d7e2a80161a9f811e41ea3c0cf12bab5cb0820c7c8539b4b88fe checksum/configuration-secret: 09216ffaa3d29e14f88b1f30af580d02a2a5e014de4d750b7f275cc07ed4e914 labels: app.kubernetes.io/component: flyte-binary @@ -1411,7 +1411,7 @@ spec: metadata: annotations: checksum/config: 8f50e768255a87f078ba8b9879a0c174c3e045ffb46ac8723d2eedbe293c8d81 - checksum/secret: a489109789725f11c861a1298e84355a6d3fa1b1ecc3d31af2370f620103ee5e + checksum/secret: 727daf2e5024ea4e541b87b717e6f9a8706552e0ae461f82b2e5260ad564766c labels: app: docker-registry release: flyte-sandbox diff --git a/docker/sandbox-bundled/manifests/complete.yaml b/docker/sandbox-bundled/manifests/complete.yaml index ad7442ba57..2b5b9d3168 100644 --- a/docker/sandbox-bundled/manifests/complete.yaml +++ b/docker/sandbox-bundled/manifests/complete.yaml @@ -457,7 +457,7 @@ data: stackdriver-enabled: false k8s: co-pilot: - image: "cr.flyte.org/flyteorg/flytecopilot:v1.10.6-b0" + image: "cr.flyte.org/flyteorg/flytecopilot:v1.10.6" k8s-array: logs: config: @@ -805,7 +805,7 @@ type: Opaque --- apiVersion: v1 data: - haSharedSecret: blpEcVV3UkZPTElZZFYyNg== + haSharedSecret: UlI4aW9PaVFzcFpyRzhkTA== proxyPassword: "" proxyUsername: "" kind: Secret @@ -1203,7 +1203,7 @@ spec: metadata: annotations: checksum/cluster-resource-templates: 6fd9b172465e3089fcc59f738b92b8dc4d8939360c19de8ee65f68b0e7422035 - checksum/configuration: 832fc20170bd24c5262c6b6a741066a2cfa308183e3adb60810396bfbe85a750 + checksum/configuration: 6755bdc74789d7e2a80161a9f811e41ea3c0cf12bab5cb0820c7c8539b4b88fe checksum/configuration-secret: 09216ffaa3d29e14f88b1f30af580d02a2a5e014de4d750b7f275cc07ed4e914 labels: app.kubernetes.io/component: flyte-binary @@ -1368,7 +1368,7 @@ spec: metadata: annotations: checksum/config: 8f50e768255a87f078ba8b9879a0c174c3e045ffb46ac8723d2eedbe293c8d81 - checksum/secret: 3948bfd9d951c74b4472f15f1a9b9dccb0eb3fbd211affa47c84178e38f03ece + checksum/secret: cb0b9e32c83fba67eefca5b8cd0a3375b07f5d5d29f6dab9a092f91ccf7bd200 labels: app: docker-registry release: flyte-sandbox diff --git a/docker/sandbox-bundled/manifests/dev.yaml b/docker/sandbox-bundled/manifests/dev.yaml index 91aebfd331..b934b7e602 100644 --- a/docker/sandbox-bundled/manifests/dev.yaml +++ b/docker/sandbox-bundled/manifests/dev.yaml @@ -499,7 +499,7 @@ metadata: --- apiVersion: v1 data: - haSharedSecret: MjRMQ25lOElMYjBrYnpzdg== + haSharedSecret: QzZJWkZlOTBQOUZxTUlvcA== proxyPassword: "" proxyUsername: "" kind: Secret @@ -933,7 +933,7 @@ spec: metadata: annotations: checksum/config: 8f50e768255a87f078ba8b9879a0c174c3e045ffb46ac8723d2eedbe293c8d81 - checksum/secret: f10919de1fb456c1eb6eb20477f5794bd87c07a138e032e3de80cf0af98a8c72 + checksum/secret: dd543013ea0e17fb3c9b7be54fe7c6063e8f15ad6e0887596011ddd7f22f1540 labels: app: docker-registry release: flyte-sandbox diff --git a/kustomize/overlays/eks/kustomization.yaml b/kustomize/overlays/eks/kustomization.yaml index 5c91c45bc4..dc0f1f3398 100644 --- a/kustomize/overlays/eks/kustomization.yaml +++ b/kustomize/overlays/eks/kustomization.yaml @@ -21,7 +21,7 @@ bases: images: # FlyteAdmin - name: flyteadmin # match images with this name - newTag: v1.10.6-b0 # FLYTEADMIN_TAG override the tag + newTag: v1.10.6 # FLYTEADMIN_TAG override the tag newName: cr.flyte.org/flyteorg/flyteadmin # override the name # FlyteConsole - name: flyteconsole # match images with this name @@ -29,15 +29,15 @@ images: newName: cr.flyte.org/flyteorg/flyteconsole # override the namep # Flyte DataCatalog - name: datacatalog # match images with this name - newTag: v1.10.6-b0 # DATACATALOG_TAG override the tag + newTag: v1.10.6 # DATACATALOG_TAG override the tag newName: cr.flyte.org/flyteorg/datacatalog # override the name # FlytePropeller - name: flytepropeller # match images with this name - newTag: v1.10.6-b0 # FLYTEPROPELLER_TAG override the tag + newTag: v1.10.6 # FLYTEPROPELLER_TAG override the tag newName: cr.flyte.org/flyteorg/flytepropeller # override the name # Webhook - name: webhook # match images with this name - newTag: v1.10.6-b0 # FLYTEPROPELLER_TAG override the tag + newTag: v1.10.6 # FLYTEPROPELLER_TAG override the tag newName: cr.flyte.org/flyteorg/flytepropeller # override the name # Override postgres image to use alpine based (rather smaller) docker image - name: postgres diff --git a/rsts/conf.py b/rsts/conf.py index 39e45d2c10..8461fdcdfb 100644 --- a/rsts/conf.py +++ b/rsts/conf.py @@ -30,7 +30,7 @@ # The short X.Y version version = "" # The full version, including alpha/beta/rc tags -release = "1.10.6-b0" +release = "1.10.6" # -- General configuration --------------------------------------------------- diff --git a/rsts/deployment/configuration/generated/flytepropeller_config.rst b/rsts/deployment/configuration/generated/flytepropeller_config.rst index 7232acd79b..b238e7c961 100644 --- a/rsts/deployment/configuration/generated/flytepropeller_config.rst +++ b/rsts/deployment/configuration/generated/flytepropeller_config.rst @@ -982,6 +982,16 @@ databricks (`databricks.Config`_) qps: 10 +echo (`testing.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + sleep-duration: 0s + + k8s (`config.K8sPluginConfig`_) ------------------------------------------------------------------------------------------------------------------------ @@ -3814,6 +3824,21 @@ All user logs across driver and executors. templates: null +testing.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +sleep-duration (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Indicates the amount of time before transitioning to success + +**Default Value**: + +.. code-block:: yaml + + 0s + + Section: propeller ======================================================================================================================== From 76114aa2e9574a1c2c7c1039deb6e46d2cd94554 Mon Sep 17 00:00:00 2001 From: Thomas Newton Date: Wed, 6 Dec 2023 15:07:37 +0000 Subject: [PATCH 08/19] Fix transient secret sync error handling (#4310) * Extra logging Signed-off-by: Thomas Newton * Hopefully fix it Signed-off-by: Thomas Newton * Remove debug prints Signed-off-by: Thomas Newton * Reduce duplication Signed-off-by: Thomas Newton * Tidy Signed-off-by: Thomas Newton * Add a test Signed-off-by: Thomas Newton * Use a CreateContainerConfigErrorGracePeriod Signed-off-by: Thomas Newton * Add grace period to error message Signed-off-by: Thomas Newton * Retryable failure with cleanup Signed-off-by: Thomas Newton * Longer grace period Signed-off-by: Thomas Newton * Fix test Signed-off-by: Thomas Newton * Set default grace period to 0 to avoid changing default behaviour Signed-off-by: Thomas Newton * Update comment Signed-off-by: Thomas Newton * Use permanent error with clean up Signed-off-by: Thomas Newton * Don't use cleanup Signed-off-by: Thomas Newton * Fix test Signed-off-by: Thomas Newton --------- Signed-off-by: Thomas Newton Co-authored-by: Dan Rammer --- .../pluginmachinery/flytek8s/config/config.go | 8 +++++ .../pluginmachinery/flytek8s/pod_helper.go | 31 ++++++++++++++--- .../flytek8s/pod_helper_test.go | 34 ++++++++++++++++--- 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/flyteplugins/go/tasks/pluginmachinery/flytek8s/config/config.go b/flyteplugins/go/tasks/pluginmachinery/flytek8s/config/config.go index 4c32d290f8..4e777ee154 100644 --- a/flyteplugins/go/tasks/pluginmachinery/flytek8s/config/config.go +++ b/flyteplugins/go/tasks/pluginmachinery/flytek8s/config/config.go @@ -49,6 +49,9 @@ var ( CreateContainerErrorGracePeriod: config2.Duration{ Duration: time.Minute * 3, }, + CreateContainerConfigErrorGracePeriod: config2.Duration{ + Duration: time.Minute * 0, + }, ImagePullBackoffGracePeriod: config2.Duration{ Duration: time.Minute * 3, }, @@ -136,6 +139,11 @@ type K8sPluginConfig struct { // one, and the corresponding task marked as failed CreateContainerErrorGracePeriod config2.Duration `json:"create-container-error-grace-period" pflag:"-,Time to wait for transient CreateContainerError errors to be resolved."` + // Time to wait for transient CreateContainerConfigError errors to be resolved. If the + // error persists past this grace period, it will be inferred to be a permanent error. + // The pod will be deleted, and the corresponding task marked as failed. + CreateContainerConfigErrorGracePeriod config2.Duration `json:"create-container-config-error-grace-period" pflag:"-,Time to wait for transient CreateContainerConfigError errors to be resolved."` + // Time to wait for transient ImagePullBackoff errors to be resolved. If the // error persists past this grace period, it will be inferred to be a permanent // one, and the corresponding task marked as failed diff --git a/flyteplugins/go/tasks/pluginmachinery/flytek8s/pod_helper.go b/flyteplugins/go/tasks/pluginmachinery/flytek8s/pod_helper.go index c326a3ddd1..d8cc4dcc7f 100644 --- a/flyteplugins/go/tasks/pluginmachinery/flytek8s/pod_helper.go +++ b/flyteplugins/go/tasks/pluginmachinery/flytek8s/pod_helper.go @@ -660,8 +660,9 @@ func DemystifyPending(status v1.PodStatus) (pluginsCore.PhaseInfo, error) { // approximation of the elapsed time since the last // transition. t := c.LastTransitionTime.Time - if time.Since(t) >= config.GetK8sPluginConfig().CreateContainerErrorGracePeriod.Duration { - return pluginsCore.PhaseInfoFailure(finalReason, finalMessage, &pluginsCore.TaskInfo{ + gracePeriod := config.GetK8sPluginConfig().CreateContainerErrorGracePeriod.Duration + if time.Since(t) >= gracePeriod { + return pluginsCore.PhaseInfoFailure(finalReason, GetMessageAfterGracePeriod(finalMessage, gracePeriod), &pluginsCore.TaskInfo{ OccurredAt: &t, }), nil } @@ -672,7 +673,22 @@ func DemystifyPending(status v1.PodStatus) (pluginsCore.PhaseInfo, error) { &pluginsCore.TaskInfo{OccurredAt: &t}, ), nil - case "CreateContainerConfigError", "InvalidImageName": + case "CreateContainerConfigError": + t := c.LastTransitionTime.Time + gracePeriod := config.GetK8sPluginConfig().CreateContainerConfigErrorGracePeriod.Duration + if time.Since(t) >= gracePeriod { + return pluginsCore.PhaseInfoFailure(finalReason, GetMessageAfterGracePeriod(finalMessage, gracePeriod), &pluginsCore.TaskInfo{ + OccurredAt: &t, + }), nil + } + return pluginsCore.PhaseInfoInitializing( + t, + pluginsCore.DefaultPhaseVersion, + fmt.Sprintf("[%s]: %s", finalReason, finalMessage), + &pluginsCore.TaskInfo{OccurredAt: &t}, + ), nil + + case "InvalidImageName": t := c.LastTransitionTime.Time return pluginsCore.PhaseInfoFailure(finalReason, finalMessage, &pluginsCore.TaskInfo{ OccurredAt: &t, @@ -680,8 +696,9 @@ func DemystifyPending(status v1.PodStatus) (pluginsCore.PhaseInfo, error) { case "ImagePullBackOff": t := c.LastTransitionTime.Time - if time.Since(t) >= config.GetK8sPluginConfig().ImagePullBackoffGracePeriod.Duration { - return pluginsCore.PhaseInfoRetryableFailureWithCleanup(finalReason, finalMessage, &pluginsCore.TaskInfo{ + gracePeriod := config.GetK8sPluginConfig().ImagePullBackoffGracePeriod.Duration + if time.Since(t) >= gracePeriod { + return pluginsCore.PhaseInfoRetryableFailureWithCleanup(finalReason, GetMessageAfterGracePeriod(finalMessage, gracePeriod), &pluginsCore.TaskInfo{ OccurredAt: &t, }), nil } @@ -715,6 +732,10 @@ func DemystifyPending(status v1.PodStatus) (pluginsCore.PhaseInfo, error) { return pluginsCore.PhaseInfoQueued(time.Now(), pluginsCore.DefaultPhaseVersion, "Scheduling"), nil } +func GetMessageAfterGracePeriod(message string, gracePeriod time.Duration) string { + return fmt.Sprintf("Grace period [%s] exceeded|%s", gracePeriod, message) +} + func DemystifySuccess(status v1.PodStatus, info pluginsCore.TaskInfo) (pluginsCore.PhaseInfo, error) { for _, status := range append( append(status.InitContainerStatuses, status.ContainerStatuses...), status.EphemeralContainerStatuses...) { diff --git a/flyteplugins/go/tasks/pluginmachinery/flytek8s/pod_helper_test.go b/flyteplugins/go/tasks/pluginmachinery/flytek8s/pod_helper_test.go index ec2f8f89da..a98bfe6b4f 100644 --- a/flyteplugins/go/tasks/pluginmachinery/flytek8s/pod_helper_test.go +++ b/flyteplugins/go/tasks/pluginmachinery/flytek8s/pod_helper_test.go @@ -1175,6 +1175,9 @@ func TestDemystifyPending(t *testing.T) { CreateContainerErrorGracePeriod: config1.Duration{ Duration: time.Minute * 3, }, + CreateContainerConfigErrorGracePeriod: config1.Duration{ + Duration: time.Minute * 4, + }, ImagePullBackoffGracePeriod: config1.Duration{ Duration: time.Minute * 3, }, @@ -1398,19 +1401,40 @@ func TestDemystifyPending(t *testing.T) { assert.Equal(t, pluginsCore.PhaseRetryableFailure, taskStatus.Phase()) }) - t.Run("CreateContainerConfigError", func(t *testing.T) { - s.ContainerStatuses = []v1.ContainerStatus{ + t.Run("CreateContainerConfigErrorWithinGracePeriod", func(t *testing.T) { + s2 := *s.DeepCopy() + s2.Conditions[0].LastTransitionTime = metav1.Now() + s2.ContainerStatuses = []v1.ContainerStatus{ { Ready: false, State: v1.ContainerState{ Waiting: &v1.ContainerStateWaiting{ Reason: "CreateContainerConfigError", - Message: "this an error", + Message: "this is a transient error", }, }, }, } - taskStatus, err := DemystifyPending(s) + taskStatus, err := DemystifyPending(s2) + assert.NoError(t, err) + assert.Equal(t, pluginsCore.PhaseInitializing, taskStatus.Phase()) + }) + + t.Run("CreateContainerConfigErrorOutsideGracePeriod", func(t *testing.T) { + s2 := *s.DeepCopy() + s2.Conditions[0].LastTransitionTime.Time = metav1.Now().Add(-config.GetK8sPluginConfig().CreateContainerConfigErrorGracePeriod.Duration) + s2.ContainerStatuses = []v1.ContainerStatus{ + { + Ready: false, + State: v1.ContainerState{ + Waiting: &v1.ContainerStateWaiting{ + Reason: "CreateContainerConfigError", + Message: "this a permanent error", + }, + }, + }, + } + taskStatus, err := DemystifyPending(s2) assert.NoError(t, err) assert.Equal(t, pluginsCore.PhasePermanentFailure, taskStatus.Phase()) }) @@ -1583,7 +1607,7 @@ func TestDemystifyPending_testcases(t *testing.T) { errCode string message string }{ - {"ImagePullBackOff", "imagepull-failurepod.json", false, "ContainersNotReady|ImagePullBackOff", "containers with unready status: [fdf98e4ed2b524dc3bf7-get-flyte-id-task-0]|Back-off pulling image \"image\""}, + {"ImagePullBackOff", "imagepull-failurepod.json", false, "ContainersNotReady|ImagePullBackOff", "Grace period [3m0s] exceeded|containers with unready status: [fdf98e4ed2b524dc3bf7-get-flyte-id-task-0]|Back-off pulling image \"image\""}, } for _, tt := range tests { From aff1150e2186eabe42936939c79ebf69c5199558 Mon Sep 17 00:00:00 2001 From: Niels Bantilan Date: Wed, 6 Dec 2023 10:26:28 -0500 Subject: [PATCH 09/19] Monodocs sphinx build (#4347) * rename rsts to docs Signed-off-by: Niels Bantilan * update docs reqs Signed-off-by: Niels Bantilan * update reqs, styles Signed-off-by: Niels Bantilan * update doc requirements Signed-off-by: Niels Bantilan * edit gitignore Signed-off-by: Niels Bantilan * update doc requirement Signed-off-by: Niels Bantilan * update doc requirements Signed-off-by: Niels Bantilan * update doc requirements Signed-off-by: Niels Bantilan * minor clean up Signed-off-by: Niels Bantilan * update deps Signed-off-by: Niels Bantilan * use doc-requirements.in in .readthedocs.yml Signed-off-by: Niels Bantilan * updates Signed-off-by: Niels Bantilan * check in new docs Signed-off-by: Niels Bantilan * clean up most reference warnings Signed-off-by: Niels Bantilan * fix ref links Signed-off-by: Niels Bantilan * update auto examples Signed-off-by: Niels Bantilan * add logic to find/replace invalid links Signed-off-by: Niels Bantilan * update docs with changes Signed-off-by: Niels Bantilan * clean up toc list for deployment docs Signed-off-by: Niels Bantilan * add back rsts Signed-off-by: Niels Bantilan * add readthedocs config for monodocs Signed-off-by: Niels Bantilan * incorporate changes from master Signed-off-by: Niels Bantilan * reformat concepts section Signed-off-by: Niels Bantilan * move monodocs readthedocs config Signed-off-by: Niels Bantilan * debug readthedocs config Signed-off-by: Niels Bantilan * add monodocs requirements Signed-off-by: Niels Bantilan * update reqs Signed-off-by: Niels Bantilan * fix furo dep Signed-off-by: Niels Bantilan * update logo Signed-off-by: Niels Bantilan * update logo Signed-off-by: Niels Bantilan * update css Signed-off-by: Niels Bantilan * update css Signed-off-by: Niels Bantilan * update sidebar caption styling Signed-off-by: Niels Bantilan * update sidebar css * use conda to install monodocs deps Signed-off-by: cosmicBboy * update conda deps Signed-off-by: cosmicBboy * update makefile docs target Signed-off-by: cosmicBboy * add furo dep to environment.yaml Signed-off-by: cosmicBboy * add retry dep Signed-off-by: cosmicBboy * update vaex deps Signed-off-by: cosmicBboy * add graphviz to ci Signed-off-by: cosmicBboy * add graphviz to readthedocs config Signed-off-by: cosmicBboy * support pointing to local flytekit, flytesnacks, flytectl - add graphviz as conda dependency - remove monodocs-requirements.{in,txt} Signed-off-by: Niels Bantilan * delete doc-requirements.txt - defer cleaning this up to followup PR Signed-off-by: Niels Bantilan * revert doc-requirements.txt Signed-off-by: Niels Bantilan --------- Signed-off-by: Niels Bantilan Signed-off-by: cosmicBboy Co-authored-by: Samhita Alla --- .github/workflows/tests.yml | 24 +- .gitignore | 17 +- .readthedocs.yml | 2 +- CHANGELOG/CHANGELOG-v0.13.0.md | 4 +- CHANGELOG/CHANGELOG-v1.3.0-b5.md | 2 +- Makefile | 4 +- RELEASE.md | 2 +- doc-requirements.txt | 200 +- docs/.readthedocs.yaml | 17 + docs/Makefile | 23 + docs/_ext/__init__.py | 0 docs/_ext/auto_examples.py | 153 + docs/_ext/import_projects.py | 139 + docs/_static/custom.css | 38 + docs/_static/flyte.css | 534 ++ docs/_templates/custom.rst | 42 + docs/_templates/file_types.rst | 39 + docs/community/contribute.rst | 737 +++ docs/community/index.rst | 127 + docs/community/roadmap.rst | 145 + docs/community/troubleshoot.rst | 135 + docs/concepts/admin.rst | 500 ++ docs/concepts/architecture.rst | 121 + docs/concepts/basics.rst | 24 + docs/concepts/catalog.rst | 63 + .../flytepropeller_architecture.rst | 81 + .../native_scheduler_architecture.rst | 77 + docs/concepts/console.rst | 128 + docs/concepts/control_plane.rst | 14 + docs/concepts/data_management.rst | 176 + docs/concepts/domains.rst | 13 + docs/concepts/dynamic_spec.rst | 50 + docs/concepts/execution_timeline.rst | 72 + docs/concepts/executions.rst | 20 + docs/concepts/flyte_console.rst | 232 + docs/concepts/flyte_wf_tasks_high_level.png | Bin 0 -> 43187 bytes docs/concepts/launchplans.rst | 57 + docs/concepts/nodes.rst | 34 + docs/concepts/projects.rst | 14 + docs/concepts/registration.rst | 33 + docs/concepts/schedules.rst | 102 + docs/concepts/state_machine.rst | 154 + docs/concepts/tasks.rst | 123 + docs/concepts/versioning.rst | 104 + docs/concepts/workflow_lifecycle.rst | 246 + docs/concepts/workflows.rst | 51 + docs/conf.py | 458 ++ docs/deployment/agents/bigquery.rst | 104 + docs/deployment/agents/index.md | 29 + docs/deployment/agents/mmcloud.rst | 119 + docs/deployment/agents/sensor.rst | 147 + .../configuration/auth_appendix.rst | 139 + .../configuration/auth_migration.rst | 162 + docs/deployment/configuration/auth_setup.rst | 790 +++ docs/deployment/configuration/cloud_event.rst | 130 + .../configuration/customizable_resources.rst | 202 + docs/deployment/configuration/eventing.rst | 64 + docs/deployment/configuration/general.rst | 740 +++ .../generated/datacatalog_config.rst | 925 +++ .../generated/flyteadmin_config.rst | 5254 ++++++++++++++++ .../generated/flytepropeller_config.rst | 5533 +++++++++++++++++ .../configuration/generated/index.md | 31 + .../generated/scheduler_config.rst | 5254 ++++++++++++++++ docs/deployment/configuration/index.md | 66 + docs/deployment/configuration/monitoring.rst | 99 + .../configuration/notifications.rst | 135 + docs/deployment/configuration/performance.rst | 264 + .../deployment/cloud_production.rst | 87 + docs/deployment/deployment/cloud_simple.rst | 132 + docs/deployment/deployment/index.rst | 159 + docs/deployment/deployment/multicluster.rst | 661 ++ docs/deployment/deployment/sandbox.rst | 114 + docs/deployment/index.md | 26 + docs/deployment/plugins/aws/athena.rst | 87 + docs/deployment/plugins/aws/batch.rst | 165 + docs/deployment/plugins/aws/index.md | 31 + docs/deployment/plugins/aws/sagemaker.rst | 98 + docs/deployment/plugins/gcp/bigquery.rst | 90 + docs/deployment/plugins/gcp/index.md | 25 + docs/deployment/plugins/index.md | 34 + docs/deployment/plugins/k8s/index.rst | 833 +++ docs/deployment/plugins/webapi/databricks.rst | 383 ++ docs/deployment/plugins/webapi/index.md | 28 + docs/deployment/plugins/webapi/snowflake.rst | 243 + docs/deployment/security/index.rst | 132 + docs/flytectl_overview.rst | 107 + docs/images/favicon-flyte-docs.png | Bin 0 -> 28517 bytes docs/images/flyte-and-lf.png | Bin 0 -> 166426 bytes docs/images/flyte_circle_gradient_1_4x4.png | Bin 0 -> 70985 bytes .../images/flyte_lockup_gradient_on_light.png | Bin 0 -> 17200 bytes docs/images/flyte_lockup_on_dark.png | Bin 0 -> 24213 bytes docs/images/logo-flyte-docs.png | Bin 0 -> 56221 bytes docs/index.md | 215 + docs/integrations.md | 215 + docs/introduction.md | 378 ++ docs/reference/index.rst | 75 + docs/reference/swagger.rst | 31 + docs/reference_flytectl.md | 11 + docs/reference_flyteidl.md | 18 + docs/reference_flytekit.md | 20 + docs/tutorials.md | 96 + docs/userguide.md | 65 + monodocs-environment.yaml | 73 + .../2704-release-cycle-process-updates.md | 4 +- rsts/deployment/deployment/sandbox.rst | 1 - script/generate_config_docs.sh | 2 +- script/generate_docs.sh | 4 +- 107 files changed, 29989 insertions(+), 172 deletions(-) create mode 100644 docs/.readthedocs.yaml create mode 100644 docs/Makefile create mode 100644 docs/_ext/__init__.py create mode 100644 docs/_ext/auto_examples.py create mode 100644 docs/_ext/import_projects.py create mode 100644 docs/_static/custom.css create mode 100644 docs/_static/flyte.css create mode 100644 docs/_templates/custom.rst create mode 100644 docs/_templates/file_types.rst create mode 100644 docs/community/contribute.rst create mode 100644 docs/community/index.rst create mode 100644 docs/community/roadmap.rst create mode 100644 docs/community/troubleshoot.rst create mode 100644 docs/concepts/admin.rst create mode 100644 docs/concepts/architecture.rst create mode 100644 docs/concepts/basics.rst create mode 100644 docs/concepts/catalog.rst create mode 100644 docs/concepts/component_architecture/flytepropeller_architecture.rst create mode 100644 docs/concepts/component_architecture/native_scheduler_architecture.rst create mode 100644 docs/concepts/console.rst create mode 100644 docs/concepts/control_plane.rst create mode 100644 docs/concepts/data_management.rst create mode 100644 docs/concepts/domains.rst create mode 100644 docs/concepts/dynamic_spec.rst create mode 100644 docs/concepts/execution_timeline.rst create mode 100644 docs/concepts/executions.rst create mode 100644 docs/concepts/flyte_console.rst create mode 100644 docs/concepts/flyte_wf_tasks_high_level.png create mode 100644 docs/concepts/launchplans.rst create mode 100644 docs/concepts/nodes.rst create mode 100644 docs/concepts/projects.rst create mode 100644 docs/concepts/registration.rst create mode 100644 docs/concepts/schedules.rst create mode 100644 docs/concepts/state_machine.rst create mode 100644 docs/concepts/tasks.rst create mode 100644 docs/concepts/versioning.rst create mode 100644 docs/concepts/workflow_lifecycle.rst create mode 100644 docs/concepts/workflows.rst create mode 100644 docs/conf.py create mode 100644 docs/deployment/agents/bigquery.rst create mode 100644 docs/deployment/agents/index.md create mode 100644 docs/deployment/agents/mmcloud.rst create mode 100644 docs/deployment/agents/sensor.rst create mode 100644 docs/deployment/configuration/auth_appendix.rst create mode 100644 docs/deployment/configuration/auth_migration.rst create mode 100644 docs/deployment/configuration/auth_setup.rst create mode 100644 docs/deployment/configuration/cloud_event.rst create mode 100644 docs/deployment/configuration/customizable_resources.rst create mode 100644 docs/deployment/configuration/eventing.rst create mode 100644 docs/deployment/configuration/general.rst create mode 100644 docs/deployment/configuration/generated/datacatalog_config.rst create mode 100644 docs/deployment/configuration/generated/flyteadmin_config.rst create mode 100644 docs/deployment/configuration/generated/flytepropeller_config.rst create mode 100644 docs/deployment/configuration/generated/index.md create mode 100644 docs/deployment/configuration/generated/scheduler_config.rst create mode 100644 docs/deployment/configuration/index.md create mode 100644 docs/deployment/configuration/monitoring.rst create mode 100644 docs/deployment/configuration/notifications.rst create mode 100644 docs/deployment/configuration/performance.rst create mode 100644 docs/deployment/deployment/cloud_production.rst create mode 100644 docs/deployment/deployment/cloud_simple.rst create mode 100644 docs/deployment/deployment/index.rst create mode 100644 docs/deployment/deployment/multicluster.rst create mode 100644 docs/deployment/deployment/sandbox.rst create mode 100644 docs/deployment/index.md create mode 100644 docs/deployment/plugins/aws/athena.rst create mode 100644 docs/deployment/plugins/aws/batch.rst create mode 100644 docs/deployment/plugins/aws/index.md create mode 100644 docs/deployment/plugins/aws/sagemaker.rst create mode 100644 docs/deployment/plugins/gcp/bigquery.rst create mode 100644 docs/deployment/plugins/gcp/index.md create mode 100644 docs/deployment/plugins/index.md create mode 100644 docs/deployment/plugins/k8s/index.rst create mode 100644 docs/deployment/plugins/webapi/databricks.rst create mode 100644 docs/deployment/plugins/webapi/index.md create mode 100644 docs/deployment/plugins/webapi/snowflake.rst create mode 100644 docs/deployment/security/index.rst create mode 100644 docs/flytectl_overview.rst create mode 100644 docs/images/favicon-flyte-docs.png create mode 100644 docs/images/flyte-and-lf.png create mode 100644 docs/images/flyte_circle_gradient_1_4x4.png create mode 100644 docs/images/flyte_lockup_gradient_on_light.png create mode 100644 docs/images/flyte_lockup_on_dark.png create mode 100644 docs/images/logo-flyte-docs.png create mode 100644 docs/index.md create mode 100644 docs/integrations.md create mode 100644 docs/introduction.md create mode 100644 docs/reference/index.rst create mode 100644 docs/reference/swagger.rst create mode 100644 docs/reference_flytectl.md create mode 100644 docs/reference_flyteidl.md create mode 100644 docs/reference_flytekit.md create mode 100644 docs/tutorials.md create mode 100644 docs/userguide.md create mode 100644 monodocs-environment.yaml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ba9208d4bd..a04cd49a50 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,16 +28,26 @@ jobs: runs-on: ubuntu-latest steps: - name: Fetch the code - uses: actions/checkout@v2 - - name: Set up Python 3.8 - uses: actions/setup-python@v2 + uses: actions/checkout@v4 + - uses: conda-incubator/setup-miniconda@v3 with: - python-version: "3.8" - - name: Install dependencies + python-version: 3.9 + mamba-version: "*" + channels: conda-forge + channel-priority: true + activate-environment: monodocs-env + environment-file: monodocs-environment.yaml + - shell: bash -el {0} run: | - python -m pip install --upgrade pip - if [ -f doc-requirements.txt ]; then pip install -r doc-requirements.txt; fi + conda info + conda list + conda config --show-sources + conda config --show + printenv | sort + - name: Setup Graphviz + uses: ts-graphviz/setup-graphviz@v1 - name: Build the documentation + shell: bash -el {0} run: make docs generate_kustomize: diff --git a/.gitignore b/.gitignore index 646cb4bec1..a8e78b52d6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,10 +10,6 @@ _repos/ _rsts/ rsts_tmp/ .doctrees/ -docs/_sources/ -docs/flytekit/flytekit.interfaces.html -docs/searchindex.js -docs/ !flyteidl/protos/docs release/ __pycache__/ @@ -33,5 +29,14 @@ dist *.db vendor/ /docker/sandbox-bundled/images/tar -rsts/_tags/ -**/bin/ \ No newline at end of file +**/bin/ +docs/_tags/ +docs/flytectl +docs/protos +docs/flytekit +docs/flytesnacks +docs/examples +docs/_src +docs/_projects +docs/api +docs/tests diff --git a/.readthedocs.yml b/.readthedocs.yml index de76f3976a..b63d11acfc 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -16,4 +16,4 @@ sphinx: # Optionally set the version of Python and requirements required to build your docs python: install: - - requirements: doc-requirements.txt + - requirements: doc-requirements.in diff --git a/CHANGELOG/CHANGELOG-v0.13.0.md b/CHANGELOG/CHANGELOG-v0.13.0.md index 8e834c660a..a06c79c5c8 100644 --- a/CHANGELOG/CHANGELOG-v0.13.0.md +++ b/CHANGELOG/CHANGELOG-v0.13.0.md @@ -2,8 +2,8 @@ ## Platform - Oauth2 support with SingleSignOn and configuration examples for popular IDP's now available in Flyte. - Please see the updated [information and description of the feature](https://github.com/flyteorg/flyte/blob/master/rsts/howto/authentication/index.rst), and the [setup information](https://github.com/flyteorg/flyte/blob/master/rsts/howto/authentication/setup.rst) - **Attention: If using Auth already - this is a BREAKING change**. refer to the [migration guide](https://github.com/flyteorg/flyte/blob/master/rsts/howto/authentication/migration.rst) to update configuration to ensure Admin continues to work. (No migration needed if auth is not turned on.) + Please see the updated [information and description of the feature](https://github.com/flyteorg/flyte/blob/master/docs/howto/authentication/index.rst), and the [setup information](https://github.com/flyteorg/flyte/blob/master/docs/howto/authentication/setup.rst) + **Attention: If using Auth already - this is a BREAKING change**. refer to the [migration guide](https://github.com/flyteorg/flyte/blob/master/docs/howto/authentication/migration.rst) to update configuration to ensure Admin continues to work. (No migration needed if auth is not turned on.) * Backend improvements to support dynamic workflow visualization (in future releases). * Lot of features added to [flytectl](https://flytectl.readthedocs.io/en/latest/) . diff --git a/CHANGELOG/CHANGELOG-v1.3.0-b5.md b/CHANGELOG/CHANGELOG-v1.3.0-b5.md index 73858bf058..81ae2e1233 100644 --- a/CHANGELOG/CHANGELOG-v1.3.0-b5.md +++ b/CHANGELOG/CHANGELOG-v1.3.0-b5.md @@ -99,7 +99,7 @@ flytectl demo start --image ghcr.io/flyteorg/flyte-sandbox-bundled:sha-e240038be ``` ### Databricks Code -You'll need to upload an [entrypoint](https://gist.github.com/pingsutw/482e7f0134414dac437500344bac5134) file to your dbfs (or S3). This is the referenced gist from the primary [Databricks plugin documentation](https://github.com/flyteorg/flyte/blob/master/rsts/deployment/plugin_setup/webapi/databricks.rst) as well, which currently only covers the `flyte-core` Helm chart installation. +You'll need to upload an [entrypoint](https://gist.github.com/pingsutw/482e7f0134414dac437500344bac5134) file to your dbfs (or S3). This is the referenced gist from the primary [Databricks plugin documentation](https://github.com/flyteorg/flyte/blob/master/docs/deployment/plugin_setup/webapi/databricks.rst) as well, which currently only covers the `flyte-core` Helm chart installation. ### User Code diff --git a/Makefile b/Makefile index 84ed86f0f8..3400f627bb 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ include boilerplate/flyte/end2end/Makefile include boilerplate/flyte/golang_test_targets/Makefile define PIP_COMPILE -pip-compile $(1) --upgrade --verbose --resolver=backtracking +pip-compile $(1) --upgrade --verbose --resolver=backtracking --annotation-style=line endef GIT_VERSION := $(shell git describe --always --tags) @@ -81,7 +81,7 @@ helm_upgrade: ## Upgrade helm charts .PHONY: docs docs: - make -C rsts clean html SPHINXOPTS=-W + make -C docs clean html SPHINXOPTS=-W .PHONY: help help: SHELL := /bin/sh diff --git a/RELEASE.md b/RELEASE.md index d4c21f95da..acd72b3c94 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -7,7 +7,7 @@ 1. Open [issues](https://github.com/flyteorg/flyte/issues) and filter by milestone and make sure they are either closed or moved over to the next milestone. ## Start a release PR 1. Run [Generate Flyte Manifests workflow](https://github.com/flyteorg/flyte/actions/workflows/generate_flyte_manifest.yml). It’ll create a PR ([example](https://github.com/flyteorg/flyte/pull/888)) -1. Update [docs version](https://github.com/flyteorg/flyte/blob/master/rsts/conf.py#L33) to match the milestone version. +1. Update [docs version](https://github.com/flyteorg/flyte/blob/master/docs/conf.py#L33) to match the milestone version. 1. Create a CHANGELOG file ([example](https://github.com/flyteorg/flyte/pull/888/files#diff-0c33dda4ecbd7e1116ddce683b5e143d85b22e43223ca258ecc571fb3b240a57)) 1. Wait for endtoend tests to finish then Merge PR. ## Create a release diff --git a/doc-requirements.txt b/doc-requirements.txt index 289144e3ad..2bde883f6a 100644 --- a/doc-requirements.txt +++ b/doc-requirements.txt @@ -1,153 +1,61 @@ # -# This file is autogenerated by pip-compile with Python 3.9 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # -# pip-compile doc-requirements.in +# pip-compile --annotation-style=line doc-requirements.in # -alabaster==0.7.13 - # via sphinx -astroid==2.15.6 - # via sphinx-autoapi -babel==2.12.1 - # via sphinx -beautifulsoup4==4.12.2 - # via - # furo - # sphinx-code-include -certifi==2023.7.22 - # via requests -cfgv==3.4.0 - # via pre-commit -charset-normalizer==3.2.0 - # via requests -codespell==2.2.6 - # via -r doc-requirements.in -distlib==0.3.7 - # via virtualenv -docutils==0.17.1 - # via - # sphinx - # sphinx-panels - # sphinx-tabs -filelock==3.12.4 - # via virtualenv -furo @ git+https://github.com/flyteorg/furo@main - # via -r doc-requirements.in -identify==2.5.29 - # via pre-commit -idna==3.4 - # via requests -imagesize==1.4.1 - # via sphinx -importlib-metadata==6.8.0 - # via sphinx -jinja2==3.0.3 - # via - # sphinx - # sphinx-autoapi - # sphinx-tabs -lazy-object-proxy==1.9.0 - # via astroid -markupsafe==2.1.3 - # via jinja2 -nodeenv==1.8.0 - # via pre-commit -packaging==23.1 - # via sphinx -platformdirs==3.10.0 - # via virtualenv -pre-commit==3.4.0 - # via sphinx-tags -pygments==2.16.1 - # via - # furo - # sphinx - # sphinx-prompt - # sphinx-tabs -pyyaml==6.0.1 - # via - # pre-commit - # sphinx-autoapi -requests==2.31.0 - # via - # sphinx - # sphinxcontrib-youtube -six==1.16.0 - # via - # sphinx-code-include - # sphinxext-remoteliteralinclude -snowballstemmer==2.2.0 - # via sphinx -soupsieve==2.5 - # via beautifulsoup4 -sphinx==4.5.0 - # via - # -r doc-requirements.in - # furo - # sphinx-autoapi - # sphinx-basic-ng - # sphinx-code-include - # sphinx-copybutton - # sphinx-fontawesome - # sphinx-issues - # sphinx-panels - # sphinx-prompt - # sphinx-tabs - # sphinx-tags - # sphinxcontrib-video - # sphinxcontrib-youtube -sphinx-autoapi==2.0.1 - # via -r doc-requirements.in -sphinx-basic-ng==1.0.0b2 - # via furo -sphinx-code-include==1.1.1 - # via -r doc-requirements.in -sphinx-copybutton==0.5.2 - # via -r doc-requirements.in -sphinx-fontawesome==0.0.6 - # via -r doc-requirements.in -sphinx-issues==3.0.1 - # via -r doc-requirements.in -sphinx-panels==0.6.0 - # via -r doc-requirements.in -sphinx-prompt==1.5.0 - # via -r doc-requirements.in -sphinx-tabs==3.4.0 - # via -r doc-requirements.in -sphinx-tags==0.2.1 - # via -r doc-requirements.in -sphinxcontrib-applehelp==1.0.4 - # via sphinx -sphinxcontrib-devhelp==1.0.2 - # via sphinx -sphinxcontrib-htmlhelp==2.0.1 - # via sphinx -sphinxcontrib-jsmath==1.0.1 - # via sphinx -sphinxcontrib-mermaid==0.9.2 - # via -r doc-requirements.in -sphinxcontrib-qthelp==1.0.3 - # via sphinx -sphinxcontrib-serializinghtml==1.1.5 - # via sphinx -sphinxcontrib-video==0.2.0 - # via -r doc-requirements.in -sphinxcontrib-youtube==1.2.0 - # via -r doc-requirements.in -sphinxext-remoteliteralinclude==0.4.0 - # via -r doc-requirements.in -typing-extensions==4.8.0 - # via astroid -unidecode==1.3.6 - # via sphinx-autoapi -urllib3==2.0.6 - # via requests -virtualenv==20.24.5 - # via pre-commit -wrapt==1.15.0 - # via astroid -zipp==3.17.0 - # via importlib-metadata +alabaster==0.7.13 # via sphinx +astroid==3.0.1 # via sphinx-autoapi +babel==2.13.1 # via sphinx +beautifulsoup4==4.12.2 # via furo, sphinx-code-include +certifi==2023.11.17 # via requests +cfgv==3.4.0 # via pre-commit +charset-normalizer==3.3.2 # via requests +codespell==2.2.6 # via -r doc-requirements.in +distlib==0.3.7 # via virtualenv +docutils==0.17.1 # via sphinx, sphinx-panels, sphinx-tabs +filelock==3.13.1 # via virtualenv +furo @ git+https://github.com/flyteorg/furo@main # via -r doc-requirements.in +identify==2.5.32 # via pre-commit +idna==3.6 # via requests +imagesize==1.4.1 # via sphinx +jinja2==3.0.3 # via sphinx, sphinx-autoapi, sphinx-tabs +markupsafe==2.1.3 # via jinja2 +nodeenv==1.8.0 # via pre-commit +packaging==23.2 # via sphinx +platformdirs==4.1.0 # via virtualenv +pre-commit==3.5.0 # via sphinx-tags +pygments==2.17.2 # via furo, sphinx, sphinx-prompt, sphinx-tabs +pyyaml==6.0.1 # via pre-commit, sphinx-autoapi +requests==2.31.0 # via sphinx, sphinxcontrib-youtube +six==1.16.0 # via sphinx-code-include, sphinxext-remoteliteralinclude +snowballstemmer==2.2.0 # via sphinx +soupsieve==2.5 # via beautifulsoup4 +sphinx==4.5.0 # via -r doc-requirements.in, furo, sphinx-autoapi, sphinx-basic-ng, sphinx-code-include, sphinx-copybutton, sphinx-fontawesome, sphinx-issues, sphinx-panels, sphinx-prompt, sphinx-tabs, sphinx-tags, sphinxcontrib-video, sphinxcontrib-youtube, sphinxext-remoteliteralinclude +sphinx-autoapi==2.0.1 # via -r doc-requirements.in +sphinx-basic-ng==1.0.0b2 # via furo +sphinx-code-include==1.1.1 # via -r doc-requirements.in +sphinx-copybutton==0.5.2 # via -r doc-requirements.in +sphinx-fontawesome==0.0.6 # via -r doc-requirements.in +sphinx-issues==3.0.1 # via -r doc-requirements.in +sphinx-panels==0.6.0 # via -r doc-requirements.in +sphinx-prompt==1.5.0 # via -r doc-requirements.in +sphinx-tabs==3.4.0 # via -r doc-requirements.in +sphinx-tags==0.2.1 # via -r doc-requirements.in +sphinxcontrib-applehelp==1.0.4 # via sphinx +sphinxcontrib-devhelp==1.0.2 # via sphinx +sphinxcontrib-htmlhelp==2.0.1 # via sphinx +sphinxcontrib-jsmath==1.0.1 # via sphinx +sphinxcontrib-mermaid==0.9.2 # via -r doc-requirements.in +sphinxcontrib-qthelp==1.0.3 # via sphinx +sphinxcontrib-serializinghtml==1.1.5 # via sphinx +sphinxcontrib-video==0.2.0 # via -r doc-requirements.in +sphinxcontrib-youtube==1.2.0 # via -r doc-requirements.in +sphinxext-remoteliteralinclude==0.4.0 # via -r doc-requirements.in +typing-extensions==4.8.0 # via astroid +unidecode==1.3.7 # via sphinx-autoapi +urllib3==2.1.0 # via requests +virtualenv==20.25.0 # via pre-commit # The following packages are considered to be unsafe in a requirements file: # setuptools diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml new file mode 100644 index 0000000000..9e9f236bc3 --- /dev/null +++ b/docs/.readthedocs.yaml @@ -0,0 +1,17 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 +build: + os: "ubuntu-22.04" + tools: + python: "mambaforge-22.9" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/conf.py + +conda: + environment: monodocs-environment.yaml diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000..0bcb4e2f47 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,23 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = flyte +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +clean: + rm -rf _build _src api flytectl flytekit flytesnacks protos examples diff --git a/docs/_ext/__init__.py b/docs/_ext/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/_ext/auto_examples.py b/docs/_ext/auto_examples.py new file mode 100644 index 0000000000..6442c52fe1 --- /dev/null +++ b/docs/_ext/auto_examples.py @@ -0,0 +1,153 @@ +"""Custom extension to auto-generate example docs from example directory.""" + +import inspect +import shutil +from pathlib import Path + +import jupytext +from docutils import nodes +from docutils.statemachine import StringList, string2lines +from sphinx.application import Sphinx +from sphinx.config import Config +from sphinx.util.docutils import SphinxDirective + +__version__ = "0.0.0" + + +TOC_TEMPLATE = """ +```{{toctree}} +:maxdepth: 1 +:hidden: +{toc} +``` +""" + +TABLE_TEMPLATE = """ +```{{list-table}} +:header-rows: 0 +:widths: 100 +{rows} +``` +""" + + +class AutoExamplesTOC(SphinxDirective): + """Custom directive to convert examples into table of contents.""" + + has_content = True + + def run(self) -> list: + return [self.parse()] + + def get_root_fp(self) -> str: + index_fp, _ = self.get_source_info() + index_fp = Path(index_fp) + example_fp = [] + example_fp = str(index_fp).split(f"{self.config.auto_examples_dir_dest}/")[-1] + return str(Path(self.config.auto_examples_dir_dest) / Path(example_fp).parent) + + def parse(self): + """Parses the directive""" + + root_fp = self.get_root_fp() + toc, rows = "", "" + for filename in self.content: + toc += f"\n{filename}" + rows += f"\n* - {{fa}}`file` {{doc}}`/{root_fp}/{filename}`" + + container = nodes.container("") + toc = inspect.cleandoc(TOC_TEMPLATE.format(toc=toc)) + table = inspect.cleandoc(TABLE_TEMPLATE.format(rows=rows)) + content = f"{toc}\n\n{table}" + + self.state.nested_parse(StringList(string2lines(content)), 0, container) + return container + + +# This allows the sphinx myst parser to recognize markdown files as something +# this it can potentially execute +MYST_NOTEBOOK_METADATA = { + "jupytext": { + "notebook_metadata_filter": "all", + "cell_metadata_filter": "all", + "formats": "md:myst", + "text_representation": { + "extension": ".md", + "format_name": "myst", + }, + }, + "kernelspec": {"display_name": "Python 3", "language": "python", "name": "python3"}, +} + + +def convert_to_mdmyst(file: Path, dest_dir: Path, from_format: str): + notebook = jupytext.read(file, fmt=from_format) + jupytext.header.recursive_update(notebook.metadata, MYST_NOTEBOOK_METADATA) + jupytext.write( + notebook, + dest_dir / f"{file.stem}.md", + fmt="md:myst", + ) + + +def convert_py_example(file: Path, dest_dir: Path): + """ + Converts a python file in the specified auto examples directory. + + Converting sphinx-gallery format python files to .rst is only supported + for backwards compatibility. The py:percent format conversion to myst + markdown is the strongly encouraged format. + """ + convert_to_mdmyst(file, dest_dir, "py:percent") + + +def generate_auto_examples(app: Sphinx, config: Config): + """Converts all example files into myst markdown format.""" + # copy files over to docs directory + if config.auto_examples_refresh: + shutil.rmtree(config.auto_examples_dir_dest) + + if Path(config.auto_examples_dir_dest).exists(): + return + + for source_dir in (x for x in Path(config.auto_examples_dir_root).glob("*") if x.is_dir()): + source_dir = Path(source_dir) + dest_dir = Path(config.auto_examples_dir_dest, *source_dir.parts[-1:]) + + dest_dir.mkdir(exist_ok=True, parents=True) + + # copy README.md file for root project content and table of contents + shutil.copy(source_dir / "README.md", dest_dir / "index.md") + + # assume that the python source files are in a directory with the same + # name as the project directory + project_name = source_dir.name + assert (source_dir / project_name).exists(), ( + "Python example files must be the same name as the project " f"directory name {project_name}" + ) + + for f in (x for x in source_dir.glob(f"{project_name}/*.py") if x.name != "__init__.py"): + # converts sphinx-gallery file to rst + convert_to_mdmyst(f, dest_dir, "py:percent") + + for f in (x for x in source_dir.glob(f"{project_name}/*.ipynb")): + convert_to_mdmyst(f, dest_dir, from_format="ipynb") + + for f in (x for x in source_dir.glob(f"{project_name}/*.md")): + convert_to_mdmyst(f, dest_dir, from_format="md") + + for f in (x for x in source_dir.glob("**/Dockerfile")): + shutil.copy(f, dest_dir) + + +def setup(app: Sphinx) -> dict: + app.add_config_value("auto_examples_refresh", None, False) + app.add_config_value("auto_examples_dir_root", None, False) + app.add_config_value("auto_examples_dir_dest", None, False) + app.connect("config-inited", generate_auto_examples, priority=2) + app.add_directive("auto-examples-toc", AutoExamplesTOC) + return { + "version": __version__, + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/docs/_ext/import_projects.py b/docs/_ext/import_projects.py new file mode 100644 index 0000000000..b4cb011012 --- /dev/null +++ b/docs/_ext/import_projects.py @@ -0,0 +1,139 @@ +import os +import re +import shutil +import subprocess +import sys +from dataclasses import dataclass, field +from functools import partial +from pathlib import Path +from typing import Optional, List, Union + +from git import Repo +from sphinx.application import Sphinx +from sphinx.config import Config + +__version__ = "0.0.0" + + +@dataclass +class ImportProjectsConfig: + clone_dir: str + flytekit_api_dir: str + source_regex_mapping: dict = field(default_factory=dict) + + +@dataclass +class Project: + source: str + dest: str + local: bool = False + cmd: Optional[List[Union[str, List[str]]]] = None + docs_path: Optional[str] = None + refresh: bool = False + + +def update_sys_path_for_flytekit(import_project_config: ImportProjectsConfig): + # add flytekit to python path + flytekit_dir = os.path.abspath(import_project_config.flytekit_api_dir) + flytekit_src_dir = os.path.abspath(os.path.join(flytekit_dir, "flytekit")) + plugins_dir = os.path.abspath(os.path.join(flytekit_dir, "plugins")) + + sys.path.insert(0, flytekit_src_dir) + sys.path.insert(0, flytekit_dir) + + # add plugins to python path + for possible_plugin_dir in os.listdir(plugins_dir): + dir_path = os.path.abspath((os.path.join(plugins_dir, possible_plugin_dir))) + plugin_path = os.path.abspath(os.path.join(dir_path, "flytekitplugins")) + if os.path.isdir(dir_path) and os.path.exists(plugin_path): + sys.path.insert(0, dir_path) + + +def import_projects(app: Sphinx, config: Config): + """Clone projects from git or copy from local directory.""" + projects = [Project(**p) for p in config.import_projects] + import_projects_config = ImportProjectsConfig(**config.import_projects_config) + + srcdir = Path(app.srcdir) + + for _dir in ( + import_projects_config.clone_dir, + import_projects_config.flytekit_api_dir, + ): + (srcdir / _dir).mkdir(parents=True, exist_ok=True) + + for project in projects: + if project.local: + local_dir = srcdir / project.source + else: + local_dir = srcdir / import_projects_config.clone_dir / project.dest + shutil.rmtree(local_dir, ignore_errors=True) + Repo.clone_from(project.source, local_dir) + + local_docs_path = local_dir / project.docs_path + dest_docs_dir = srcdir / project.dest + + if project.refresh or not dest_docs_dir.exists(): + shutil.rmtree(dest_docs_dir, ignore_errors=True) + shutil.copytree(local_docs_path, dest_docs_dir, dirs_exist_ok=True) + + if project.cmd: + if isinstance(project.cmd[0], list): + for c in project.cmd: + subprocess.run(c) + else: + subprocess.run(project.cmd) + + # remove cloned directories + shutil.rmtree(import_projects_config.clone_dir) + + # add flytekit and plugins to path so that API reference can build + update_sys_path_for_flytekit(import_projects_config) + + # add functions to clean up source and docstring refs + for i, (patt, repl) in enumerate(import_projects_config.source_regex_mapping.items()): + app.connect( + "source-read", + partial(replace_refs_in_files, patt, repl), + priority=i, + ) + app.connect( + "autodoc-process-docstring", + partial(replace_refs_in_docstrings, patt, repl), + priority=i, + ) + + +def replace_refs_in_files(patt: str, repl: str, app: Sphinx, docname: str, source: List[str]): + text = source[0] + + if re.search(patt, text): + text = re.sub(patt, repl, text) + + # replace source file + source[0] = text + + +def replace_refs_in_docstrings( + patt: str, repl: str, app: Sphinx, what: str, name: str, obj: str, options: dict, lines: List[str], +): + replace = {} + for i, text in enumerate(lines): + if re.search(patt, text): + text = re.sub(patt, repl, text) + replace[i] = text + + for i, text in replace.items(): + lines[i] = text + + +def setup(app: Sphinx) -> dict: + app.add_config_value("import_projects_config", None, False) + app.add_config_value("import_projects", None, False) + app.connect("config-inited", import_projects, priority=0) + + return { + "version": __version__, + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 0000000000..f9687a7b15 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,38 @@ +.getting-started-panels div.card-body { + padding: 0; +} + +.getting-started-panels a.btn-primary { + color: white !important; + background-color: var(--color-link); + border-color: var(--color-link); +} + +.getting-started-panels a.btn-outline-primary { + color: white !important; + background-color: var(--color-link); + opacity: 0.5; + border-color: var(--color-link); +} + +html .tabbed-set > label { + color: var(--color-foreground-border); +} + +html .tabbed-set > input:checked + label { + border-color: var(--color-link); + color: var(--color-link); +} + +html .tabbed-set > label:hover { + color: var(--color-link); +} + +html .tabbed-content { + box-shadow: 0 -.0625rem var(--color-background-border),0 .0625rem var(--color-background-border); +} + +table { + width: 100%; + box-shadow: none !important; +} diff --git a/docs/_static/flyte.css b/docs/_static/flyte.css new file mode 100644 index 0000000000..a0e5225c25 --- /dev/null +++ b/docs/_static/flyte.css @@ -0,0 +1,534 @@ +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 400; + margin-top: 1.75rem; +} + +.sidebar-scroll { + scroll-behavior: auto; +} + +.sidebar-tree ul:first-child li:not(:last-child) { + margin-bottom: 5px; +} + +.sidebar-tree .caption { + text-transform: none; + margin-bottom: 12px; + margin-left: 16px; + margin-top: 30px; +} + +.sidebar-tree li.current-page > a.current { + background: #9d68e41f; + font-weight: unset; +} + +.sidebar-tree li.current-page.toctree-l2 > a.current { + background: var(--color-sidebar-item-background--hover); + font-weight: unset; +} + +/* Algolia Docs Search Style */ +.docsearch { + width: 100% !important; +} + +.DocSearch-Button { + height: 60px !important; + width: 100% !important; + margin: 0px !important; + border-radius: 0 !important; + border-bottom: 1px solid var(--color-header-border) !important; + background: var(--color-sidebar-background) !important; + padding: 0 15px !important; +} + +.DocSearch-Button:hover, .DocSearch-Button:active { + box-shadow: none !important; + background: var(--docsearch-searchbox-background) !important; +} + +.sidebar-search-container::before { + content: none; +} + +.tabbed-set > input:checked + label { + border-color: var(--color-link); + color: var(--color-link); +} + +.tabbed-set > input:checked + label:hover { + color: var(--color-link); +} + +@media only screen and (min-width: 1200px) { + .sidebar-drawer { + width: 20em; + } +} + +.sidebar-brand { + flex-direction: row; + align-items: center; + justify-content: center; +} + +.sidebar-brand-text { + font-size: 2.5em; + line-height: 2.5em; +} + +.sidebar-container { + width: 20em; +} + +.sidebar-logo { + max-width: 60px; + margin: 0 15px 0 0; + float: right; +} + +.sidebar-tree i.fa { + padding-right: 15px; + width: 1.75em; + text-align: center; +} + +.sidebar-tree .caption { + padding: 0; +} + +.caption-text { + font-size: 15px; + font-weight: 600; + color: #696969; +} + +/* .sidebar-tree .reference.external:after { + content: none; +} */ + +.sphx-glr-thumbnails { + display: block; +} + +.sphx-glr-thumbcontainer { + background-color: var(--color-background-secondary); + border: 1px solid var(--color-background-border); + box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), + 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important; + min-height: 60px; + width: 100%; + padding-top: 0px; + margin: 10px 0; + display: block; +} + +.sphx-glr-thumbcontainer:hover { + border: 1px solid #cca9ff; + background-color: #f2e9ff; + box-shadow: none !important; +} + +body:not([data-theme="light"]) .sphx-glr-thumbcontainer:hover { + border: 1px solid #2a144a; + background-color: #2a144a; +} + +.sphx-glr-thumbcontainer img { + float: left; + width: 30px; + margin-top: 14px; + margin-left: 14px; + opacity: 0.5; +} + +.sphx-glr-thumbnail-title { + margin-top: 18px; + margin-left: 65px; + color: #696969; + font-size: 15px; +} + +div.sphx-glr-download-link-note, +p.sphx-glr-signature { + height: 0px; + visibility: hidden; + padding: 0; + margin: 0; +} + +div.sphx-glr-footer { + width: 100%; + display: flex; + border-top: 1px solid var(--color-background-border); + border-bottom: 1px solid var(--color-background-border); + margin: 40px 0px 10px 0px; +} + +div.sphx-glr-download { + margin: 0; + width: 50%; +} + +.sphx-glr-thumbcontainer a.internal { + position: absolute; + padding: 10px; + padding-left: 75px; + font-size: 0.9rem; + text-decoration: none; + color: var(--color-sidebar-link-text); + /* center text in example cards */ + display: flex; + justify-content: left; + align-items: center; +} + +.sphx-glr-thumbcontainer:hover a.internal { + text-decoration: none; + color: var(--color-link); +} + +/* hide download thumbnail captions and sphinx gallery script timing */ +.sphx-glr-thumbcontainer[tooltip]:hover:before, +.sphx-glr-thumbcontainer[tooltip]:hover:after, +.sphx-glr-timing { + display: none; +} + +div.sphx-glr-download a { + color: var(--color-sidebar-link-text); + background: transparent; + background-image: none; + border: none; + border-radius: 0; + font-family: inherit; + font-weight: lighter; + font-size: 0.9em; + padding: 30px 0px; + width: 100%; +} + +div.sphx-glr-download a:hover { + box-shadow: none; + background: var(--color-sidebar-item-background--hover); + border: none; + border-radius: 0; +} + +div.sphx-glr-footer div.sphx-glr-download p { + margin: 0; +} + +div.sphx-glr-footer div.sphx-glr-download:first-child p { + border-right: 1px solid var(--color-background-border); +} + +div.sphx-glr-thumbcontainer a.headerlink { + display: none; +} + +.sphx-glr-script-out .highlight pre { + background-color: #f8f8f8; +} + +p.sphx-glr-script-out { + padding-top: 0em; +} + +.search__outer::-webkit-scrollbar-track { + border-radius: 0px; +} + +@media (prefers-color-scheme: dark) { + .search__outer { + background-color: #131416 !important; + border: 1px solid #131416 !important; + } + .search__outer__input { + background-color: #1a1c1e !important; + } + .search__result__single { + border-bottom: #303335 !important; + } + .outer_div_page_results:hover { + background-color: black; + } + .search__result__title, + .rtd_ui_search_subtitle { + color: #9d68e4 !important; + border-bottom: 1px solid #9d68e4 !important; + } + .search__outer .search__result__title span, + .search__outer .search__result__content span { + background-color: #9d68e454; + } + .search__result__subheading, + .search__result__content { + color: #ffffffd9 !important; + } + .search__outer::-webkit-scrollbar-track { + background-color: #131416 !important; + } + .rtd__search__credits { + background-color: #1a1c1e !important; + border: 1px solid #1a1c1e !important; + color: #81868d !important; + } + .rtd__search__credits a, + .search__error__box { + color: #9ca0a5 !important; + } + details.sphinx-bs.dropdown { + background: var(--color-background-primary); + border: 1px solid var(--color-background-border); + } + details.sphinx-bs.dropdown .card-header { + color: var(--color-link); + } +} + +div.sphinx-bs .card { + flex-direction: row; +} + +/* sphinx-panels custom styles */ +div.sphinx-bs .card-header { + border-bottom: none; + background-color: var(--color-background-primary); + display: flex; + align-items: center; + justify-content: left; + width: 35%; + float: left; +} + +.sphinx-bs .card-header:first-child { + border-radius: calc(0.25rem - 1px) 0 0 calc(0.25rem - 1px); +} + +div.sphinx-bs .card-header .sphinx-bs.btn, +div.sphinx-bs .card-body .sphinx-bs.btn, +div.sphinx-bs .card-header p.card-text { + font-size: 1rem; + text-decoration: none; + word-spacing: 2.5px; + color: var(--color-sidebar-link-text); +} + +div.sphinx-bs .card-header p.card-text a { + text-align: left; +} + +.sphinx-bs.btn:focus { + box-shadow: none; +} + +div.sphinx-bs .card-body { + width: 65%; + float: left; +} + +.sphinx-bs .card-body .fa { + color: var(--color-sidebar-link-text); +} + +.sphinx-bs .card-body:hover .fa { + color: var(--color-link--hover); +} + +.sphinx-bs .card-body .fa { + font-size: 2rem; +} + +div.sphinx-bs .card:hover { + box-shadow: none !important; + border-color: #cca9ff; +} + +div.sphinx-bs .card:hover .card-header { + background-color: #f2e9ff; + color: #fff; +} + +body[data-theme="dark"] div.sphinx-bs .card:hover { + border-color: #2a144a; +} + +body[data-theme="dark"] div.sphinx-bs .card:hover .card-header { + background-color: #2a144a; + color: #fff; +} + +/* make sure hover style is consistent if user prefers dark theme at OS level */ +@media (prefers-color-scheme: dark) { + body:not([data-theme="light"]) div.sphinx-bs .card:hover { + border-color: #2a144a; + } + body:not([data-theme="light"]) div.sphinx-bs .card:hover .card-header { + background-color: #2a144a; + color: #fff; + } +} + +div.sphinx-bs .card:hover .sphinx-bs.btn { + color: var(--color-link); +} + +div.sphinx-bs .card:hover .card-body .sphinx-bs.btn { + color: var(--color-link--hover); +} + +.getting-started-panels div.sphinx-bs .sphinx-bs.btn:hover { + border-color: var(--color-link); + background-color: #9d68e4; + color: #ffffff; +} + +div.sphinx-bs .card { + background-color: var(--color-background-secondary); + border: 1px solid var(--color-background-border); +} + +.center-card-content p { + margin: auto !important; +} + +.sphinx-tabs { + padding-top: 10px; +} + +.sphinx-tabs-tab { + color: var(--color-link); +} + +/* sphinx tabs */ +.sphinx-tabs-tab[aria-selected="true"] { + background-color: var(--color-background-primary); + border: 1px solid var(--color-background-border); + border-bottom: 1px solid var(--color-background-primary); +} + +.sphinx-tabs-panel { + border: 1px solid var(--color-background-border); + background: var(--color-background-primary); + border-top: 0; +} + +[role="tablist"] { + border-bottom: 1px solid var(--color-background-border); +} + +/* mermaid diagrams */ +div.mermaid { + /* hide the div if the raw data hasn't been processed */ + display: none; +} + +div.mermaid[data-processed="true"] { + display: block; + background: var(--color-background-secondary); + padding: 20px 0; +} + +div.mermaid svg { + max-height: 800px; +} + +div.mermaid .messageText { + fill: var(--color-foreground-primary) !important; + stroke: var(--color-foreground-primary) !important; +} + +div.mermaid line { + stroke: var(--color-foreground-secondary) !important; +} + +/* code cell styles */ +div.highlight a { + text-decoration-color: var(--color-content-foreground); +} + +div.sphx-glr-script-out .highlight { + margin-left: 0; + margin-top: 0; +} + +.sphx-glr-script-out .highlight pre { + background-color: var(--color-background-secondary); +} + +/* Make sure autosummary table cells have left text alignment */ +.article .align-center, +article .align-default { + text-align: left; +} + +/* rate-the-docs custom styles */ +.ratd-widget { + z-index: 10000 !important; + right: 0 !important; + font-size: 0.85em !important; + background-color: var(--color-sidebar-background) !important; + border: 1px solid var(--color-sidebar-background-border) !important; + color: var(--color-sidebar-link-text) !important; +} + +.ratd-widget .btn { + color: var(--color-sidebar-link-text) !important; +} + +.ratd-toggle.ratd-toggle-close { + margin: 12px 0 !important; +} + +.ratd-panel-thanks { + padding-top: 10px !important; +} + +.ratd-panel-thanks[aria-hidden="true"] { + padding-top: 0px !important; +} + +.ratd-widget .ratd-panel-suggestion .btn { + background-color: var(--color-link); + border-color: var(--color-link); + color: var(--color-content-foreground) !important; +} + +.ratd-widget i { + color: var(--color-foreground-muted) !important; +} + +/* readthedocs custom styling */ +.rst-versions.rst-badge { + bottom: 80px !important; + max-width: none !important; +} + +.rst-versions.rst-badge.shift-up .rst-current-version .fa-book { + padding-top: 8px !important; +} + +/* tag styles */ +p.tags span { + font-weight: bold +} + +p.tags a { + background: var(--color-background-secondary); + border: 1px solid var(--color-background-border); + padding: 5px 10px; + border-radius: 10px; + font-size: 0.9em; + margin-right: 5px; +} + +p.tags span:not(:first-child) { + display: none; +} diff --git a/docs/_templates/custom.rst b/docs/_templates/custom.rst new file mode 100644 index 0000000000..17c9b00963 --- /dev/null +++ b/docs/_templates/custom.rst @@ -0,0 +1,42 @@ +{{ fullname | escape | underline}} + +.. currentmodule:: {{ module }} + +{% if objtype == 'class' %} + +.. autoclass:: {{ objname }} + + {% block methods %} + {% if methods %} + + .. rubric:: {{ _('Methods') }} + {% for item in methods %} + + {% if item != '__init__' %} + .. automethod:: {{ item }} + {% endif %} + + {%- endfor %} + {% endif %} + {% endblock %} + + {% block attributes %} + {% if attributes %} + + .. rubric:: {{ _('Attributes') }} + {% for item in attributes %} + .. autoattribute:: {{ item }} + :noindex: + {%- endfor %} + + {% endif %} + {% endblock %} + + +{% endif %} + +{% if objtype == 'function' %} + +.. autofunction:: {{ objname }} + +{% endif %} diff --git a/docs/_templates/file_types.rst b/docs/_templates/file_types.rst new file mode 100644 index 0000000000..e7629ea363 --- /dev/null +++ b/docs/_templates/file_types.rst @@ -0,0 +1,39 @@ +{{ fullname | escape | underline}} + +.. currentmodule:: {{ module }} + +{% if objname == 'FlyteFile' %} + +.. autoclass:: {{ objname }} + + {% block methods %} + {% if methods %} + + .. rubric:: {{ _('Methods') }} + {% for item in methods %} + + {% if item != '__init__' %} + .. automethod:: {{ item }} + {% endif %} + + {%- endfor %} + {% endif %} + {% endblock %} + + {% block attributes %} + {% if attributes %} + + .. rubric:: {{ _('Attributes') }} + {% for item in attributes %} + .. autoattribute:: {{ item }} + {%- endfor %} + + {% endif %} + {% endblock %} + + +{% else %} + +.. autodata:: {{ objname }} + +{% endif %} diff --git a/docs/community/contribute.rst b/docs/community/contribute.rst new file mode 100644 index 0000000000..b914769f93 --- /dev/null +++ b/docs/community/contribute.rst @@ -0,0 +1,737 @@ +.. _contribute_Flyte: + +##################### +Contributing to Flyte +##################### + +.. tags:: Contribute, Basic + +Thank you for taking the time to contribute to Flyte! +Please read our `Code of Conduct `__ before contributing to Flyte. + +Here are some guidelines for you to follow, which will make your first and follow-up contributions easier. + +TL;DR: Find the repo-specific contribution guidelines in the `Component Reference <#component-reference>`__ section. + +💻 Becoming a contributor +========================= + +An issue tagged with `good first issue `__ is the best place to start for first-time contributors. + +**Appetizer for every repo: Fork and clone the concerned repository. Create a new branch on your fork and make the required changes. Create a pull request once your work is ready for review.** + +.. note:: + To open a pull request, refer to `GitHub's guide `__ for detailed instructions. + +Example PR for your reference: `GitHub PR `__. +A couple of checks are introduced to help maintain the robustness of the project. + +#. To get through DCO, sign off on every commit (`Reference `__) +#. To improve code coverage, write unit tests to test your code +#. Make sure all the tests pass. If you face any issues, please let us know + +On a side note, format your Go code with ``golangci-lint`` followed by ``goimports`` (use ``make lint`` and ``make goimports``), and Python code with ``black`` and ``isort`` (use ``make fmt``). +If make targets are not available, you can manually format the code. +Refer to `Effective Go `__, `Black `__, and `Isort `__ for full coding standards. + +As you become more involved with the project, you may be able to be added as a contributor to the repos you're working on, +but there is a medium term effort to move all development to forks. + +📃 Documentation +================ + +Flyte uses Sphinx for documentation. ``protoc-gen-doc`` is used to generate the documentation from ``.proto`` files. + +Sphinx spans multiple repositories under `flyteorg `__. It uses reStructured Text (rst) files to store the documentation content. +For API- and code-related content, it extracts docstrings from the code files. + +To get started, refer to the `reStructuredText reference `__. + +For minor edits that don't require a local setup, you can edit the GitHub page in the documentation to propose improvements. + +Intersphinx +*********** + +`Intersphinx `__ can generate automatic links to the documentation of objects in other projects. + +To establish a reference to any other documentation from Flyte or within it, use Intersphinx. + +To do so, create an ``intersphinx_mapping`` in the ``conf.py`` file which should be present in the respective ``docs`` repository. +For example, ``rsts`` is the docs repository for the ``flyte`` repo. + +For example: + +.. code-block:: python + + intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "flytekit": ("https://flyte.readthedocs.io/projects/flytekit/en/master/", None), + } + +The key refers to the name used to refer to the file (while referencing the documentation), and the URL denotes the precise location. + +Here is an example using ``:std:doc``: + +* Direct reference + + .. code-block:: text + + Task: :std:doc:`/api/flytekit/generated/flytekit.task` + + Output: + + Task: :std:doc:`/api/flytekit/generated/flytekit.task` + +* Custom name + + .. code-block:: text + + :std:doc:`Using custom words ` + + Output: + + :std:doc:`Using custom words ` + +| + +You can cross-reference multiple Python objects. Check out this `section `__ to learn more. + +| + +For instance, `task` decorator in flytekit uses the ``func`` role. + +.. code-block:: text + + Link to flytekit code :py:func:`flytekit:flytekit.task` + +Output: + +Link to flytekit code :py:func:`flytekit:flytekit.task` + +| + +Here are a couple more examples. + +.. code-block:: text + + :py:mod:`Module ` + :py:class:`Class ` + :py:data:`Data ` + :py:func:`Function ` + :py:meth:`Method ` + +Output: + +:py:mod:`Module ` + +:py:class:`Class ` + +:py:data:`Data ` + +:py:func:`Function ` + +:py:meth:`Method ` + +🧱 Component reference +====================== + +To understand how the below components interact with each other, refer to :ref:`Understand the lifecycle of a workflow `. + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/contribution_guide/dependency_graph.png + :alt: Dependency graph between various flyteorg repos + :align: center + :figclass: align-center + + The dependency graph between various flyte repos + +``flyte`` +********* + +.. list-table:: + + * - `Repo `__ + * - **Purpose**: Deployment, Documentation, and Issues + * - **Languages**: Kustomize & RST + +.. note:: + For the ``flyte`` repo, run the following command in the repo's root to generate documentation locally. + + .. code-block:: console + + make -C rsts html + +``flyteidl`` +************ + +.. list-table:: + + * - `Repo `__ + * - **Purpose**: Flyte workflow specification is in `protocol buffers `__ which forms the core of Flyte + * - **Language**: Protobuf + * - **Guidelines**: Refer to the `README `__ + +``flytepropeller`` +****************** + +.. list-table:: + + * - `Repo `__ | `Code Reference `__ + * - **Purpose**: Kubernetes-native operator + * - **Language**: Go + * - **Guidelines:** + + * Check for Makefile in the root repo + * Run the following commands: + * ``make generate`` + * ``make test_unit`` + * ``make link`` + * To compile, run ``make compile`` + +``flyteadmin`` +************** + +.. list-table:: + + * - `Repo `__ | `Code Reference `__ + * - **Purpose**: Control Plane + * - **Language**: Go + * - **Guidelines**: + + * Check for Makefile in the root repo + * If the service code has to be tested, run it locally: + * ``make compile`` + * ``make server`` + * To seed data locally: + * ``make compile`` + * ``make seed_projects`` + * ``make migrate`` + * To run integration tests locally: + * ``make integration`` + * (or to run in containerized dockernetes): ``make k8s_integration`` + +``flytekit`` +************ + +.. list-table:: + + * - `Repo `__ + * - **Purpose**: Python SDK & Tools + * - **Language**: Python + * - **Guidelines**: Refer to the `Flytekit Contribution Guide `__ + +``flyteconsole`` +**************** + +.. list-table:: + + * - `Repo `__ + * - **Purpose**: Admin Console + * - **Language**: Typescript + * - **Guidelines**: Refer to the `README `__ + +``datacatalog`` +*************** + +.. list-table:: + + * - `Repo `__ | `Code Reference `__ + * - **Purpose**: Manage Input & Output Artifacts + * - **Language**: Go + +``flyteplugins`` +**************** + +.. list-table:: + + * - `Repo `__ | `Code Reference `__ + * - **Purpose**: Flyte Plugins + * - **Language**: Go + * - **Guidelines**: + + * Check for Makefile in the root repo + * Run the following commands: + * ``make generate`` + * ``make test_unit`` + * ``make link`` + +``flytestdlib`` +*************** + +.. list-table:: + + * - `Repo `__ + * - **Purpose**: Standard Library for Shared Components + * - **Language**: Go + +``flytesnacks`` +*************** + +.. list-table:: + + * - `Repo `__ + * - **Purpose**: Examples, Tips, and Tricks to use Flytekit SDKs + * - **Language**: Python (In the future, Java examples will be added) + * - **Guidelines**: Refer to the `Flytesnacks Contribution Guide `__ + +``flytectl`` +************ + +.. list-table:: + + * - `Repo `__ + * - **Purpose**: A standalone Flyte CLI + * - **Language**: Go + * - **Guidelines**: Refer to the `FlyteCTL Contribution Guide `__ + + +🔮 Development Environment Setup Guide +====================================== + +This guide provides a step-by-step approach to setting up a local development environment for +`flyteidl `_, `flyteadmin `_, +`flyteplugins `_, `flytepropeller `_, +`flytekit `_ , `flyteconsole `_, +`datacatalog `_, and `flytestdlib `_. + +The video below is a tutorial on how to set up a local development environment for Flyte. + +.. youtube:: V-KlVQmQAjE + +Requirements +************ + +This guide has been tested and used on AWS EC2 with an Ubuntu 22.04 +image. The following tools are required: + +- `Docker `__ +- `Kubectl `__ +- `Go `__ + +Content +******* + +- `How to setup dev environment for flyteidl, flyteadmin, flyteplugins, + flytepropeller, datacatalog and flytestdlib? <#how-to-setup-dev-environment-for-flyteidl-flyteadmin-flyteplugins-flytepropeller-datacatalog-and-flytestdlib>`__ + +- `How to setup dev environment for + flytekit? <#how-to-setup-dev-environment-for-flytekit>`__ + +- `How to setup dev environment for + flyteconsole? <#how-to-setup-dev-environment-for-flyteconsole>`__ + +- `How to access Flyte UI, minio, postgres, k3s, and endpoints? + <#how-to-access-flyte-ui-minio-postgres-k3s-and-endpoints>`__ + +How to setup dev environment for flyteidl, flyteadmin, flyteplugins, flytepropeller, datacatalog and flytestdlib? +****************************************************************************************************************************** + +**1. Install flytectl** + + +`Flytectl `__ is a portable and lightweight command-line interface to work with Flyte. + +.. code:: shell + + # Step1: Install the latest version of flytectl + curl -sL https://ctl.flyte.org/install | bash + # flyteorg/flytectl info checking GitHub for latest tag + # flyteorg/flytectl info found version: 0.6.39 for v0.6.39/Linux/x86_64 + # flyteorg/flytectl info installed ./bin/flytectl + + # Step2: Export flytectl path based on the previous log "flyteorg/flytectl info installed ./bin/flytectl" + export PATH=$PATH:/home/ubuntu/bin # replace with your path + +**2. Build a k3s cluster that runs minio and postgres Pods.** + + +| `Minio `__ is an S3-compatible object store that will be used later to store task output, input, etc. +| `Postgres `__ is an open-source object-relational database that will later be used by flyteadmin/dataCatalog to + store all Flyte information. + +.. code:: shell + + # Step1: Start k3s cluster, create Pods for postgres and minio. Note: We cannot access Flyte UI yet! but we can access the minio console now. + flytectl demo start --dev + # 👨‍💻 Flyte is ready! Flyte UI is available at http://localhost:30080/console 🚀 🚀 🎉 + # ❇️ Run the following command to export demo environment variables for accessing flytectl + # export FLYTECTL_CONFIG=/home/ubuntu/.flyte/config-sandbox.yaml + # 🐋 Flyte sandbox ships with a Docker registry. Tag and push custom workflow images to localhost:30000 + # 📂 The Minio API is hosted on localhost:30002. Use http://localhost:30080/minio/login for Minio console + + # Step2: Export FLYTECTL_CONFIG as the previous log indicated. + FLYTECTL_CONFIG=/home/ubuntu/.flyte/config-sandbox.yaml + + # Step3: The kubeconfig will be automatically copied to the user's main kubeconfig (default is `/.kube/config`) with "flyte-sandbox" as the context name. + # Check that we can access the K3s cluster. Verify that postgres and minio are running. + kubectl get pod -n flyte + # NAME READY STATUS RESTARTS AGE + # flyte-sandbox-docker-registry-85745c899d-dns8q 1/1 Running 0 5m + # flyte-sandbox-kubernetes-dashboard-6757db879c-wl4wd 1/1 Running 0 5m + # flyte-sandbox-proxy-d95874857-2wc5n 1/1 Running 0 5m + # flyte-sandbox-minio-645c8ddf7c-sp6cc 1/1 Running 0 5m + # flyte-sandbox-postgresql-0 1/1 Running 0 5m + + +**3. Run all Flyte components (flyteadmin, flytepropeller, datacatalog, flyteconsole, etc) in a single binary.** + +The `Flyte repository `__ includes Go code +that integrates all Flyte components into a single binary. + +.. code:: shell + + # Step1: Clone flyte repo + git clone https://github.com/flyteorg/flyte.git + cd flyte + + # Step2: Build a single binary that bundles all the Flyte components. + # The version of each component/library used to build the single binary are defined in `go.mod`. + sudo apt-get -y install jq # You may need to install jq + go mod tidy + make compile + + # Step3: Edit the config file: ./flyte-single-binary-local.yaml. + # Replace occurrences of $HOME with the actual path of your home directory. + sedi=(-i) + case "$(uname)" in + Darwin*) sedi=(-i "") + esac + sed "${sedi[@]}" -e "s|\$HOME|${HOME}|g" flyte-single-binary-local.yaml + + # Step 4: Prepare a namespace template for the cluster resource controller. + # The configuration file "flyte-single-binary-local.yaml" has an entry named cluster_resources.templatePath. + # This entry needs to direct to a directory containing the templates for the cluster resource controller to use. + # We will now create a simple template that allows the automatic creation of required namespaces for projects. + # For example, with Flyte's default project "flytesnacks", the controller will auto-create the following namespaces: + # flytesnacks-staging, flytesnacks-development, and flytesnacks-production. + mkdir $HOME/.flyte/cluster-resource-templates/ + echo "apiVersion: v1 + kind: Namespace + metadata: + name: '{{ namespace }}'" > $HOME/.flyte/cluster-resource-templates/namespace.yaml + + # Step5: Running the single binary. + # The POD_NAMESPACE environment variable is necessary for the webhook to function correctly. + # You may encounter an error due to `ERROR: duplicate key value violates unique constraint`. Running the command again will solve the problem. + POD_NAMESPACE=flyte ./flyte start --config flyte-single-binary-local.yaml + # All logs from flyteadmin, flyteplugins, flytepropeller, etc. will appear in the terminal. + + +**4. Build single binary with your own code.** + + +The following instructions provide guidance on how to build single binary with your customized code under the ``flyteadmin`` as an example. + + +- **Note** Although we'll use ``flyteadmin`` as an example, these steps can be applied to other Flyte components or libraries as well. + ``{flyteadmin}`` below can be substituted with other Flyte components/libraries: ``flyteidl``, ``flyteplugins``, ``flytepropeller``, ``datacatalog``, or ``flytestdlib``. +- **Note** If you want to learn how flyte compiles those components and replace the repositories, you can study how ``go mod edit`` works. + +.. code:: shell + + # Step1: Install Go. Flyte uses Go 1.19, so make sure to switch to Go 1.19. + export PATH=$PATH:$(go env GOPATH)/bin + go install golang.org/dl/go1.19@latest + go1.19 download + export GOROOT=$(go1.19 env GOROOT) + export PATH="$GOROOT/bin:$PATH" + + # You may need to install goimports to fix lint errors. + # Refer to https://pkg.go.dev/golang.org/x/tools/cmd/goimports + go install golang.org/x/tools/cmd/goimports@latest + export PATH=$(go env GOPATH)/bin:$PATH + + # Step2: Go to the {flyteadmin} repository, modify the source code accordingly. + cd flyte/flyteadmin + + # Step3: Now, you can build the single binary. Go back to Flyte directory. + go mod tidy + make compile + POD_NAMESPACE=flyte ./flyte start --config flyte-single-binary-local.yaml + +**5. Test by running a hello world workflow.** + + +.. code:: shell + + # Step1: Install flytekit + pip install flytekit && export PATH=$PATH:/home/ubuntu/.local/bin + + # Step2: Run a hello world example + pyflyte run --remote https://raw.githubusercontent.com/flyteorg/flytesnacks/master/examples/basics/basics/hello_world.py hello_world_wf + # Go to http://localhost:30080/console/projects/flytesnacks/domains/development/executions/fd63f88a55fed4bba846 to see execution in the console. + # You can go to the [flytesnacks repository](https://github.com/flyteorg/flytesnacks) to see more useful examples. + +**6. Tear down the k3s cluster after finishing developing.** + + +.. code:: shell + + flytectl demo teardown + # context removed for "flyte-sandbox". + # 🧹 🧹 Sandbox cluster is removed successfully. + # ❇️ Run the following command to unset sandbox environment variables for accessing flytectl + # unset FLYTECTL_CONFIG + +How to setup dev environment for flytekit? +******************************************* + +**1. Set up local Flyte Cluster.** + + +If you are also modifying the code for flyteidl, flyteadmin, flyteplugins, flytepropeller datacatalog, or flytestdlib, +refer to the instructions in the `previous section <#how-to-setup-dev-environment-for-flyteidl-flyteadmin-flyteplugins-flytepropeller-datacatalog-and-flytestdlib>`__ to set up a local Flyte cluster. + +If not, we can start backends with a single command. + +.. code:: shell + + # Step1: Install the latest version of flytectl, a portable and lightweight command-line interface to work with Flyte. + curl -sL https://ctl.flyte.org/install | bash + # flyteorg/flytectl info checking GitHub for latest tag + # flyteorg/flytectl info found version: 0.6.39 for v0.6.39/Linux/x86_64 + # flyteorg/flytectl info installed ./bin/flytectl + + # Step2: Export flytectl path based on the previous log "flyteorg/flytectl info installed ./bin/flytectl" + export PATH=$PATH:/home/ubuntu/bin # replace with your path + + # Step3: Starts the Flyte demo cluster. This will setup a k3s cluster running minio, postgres Pods, and all Flyte components: flyteadmin, flyteplugins, flytepropeller, etc. + # See https://docs.flyte.org/projects/flytectl/en/latest/gen/flytectl_demo_start.html for more details. + flytectl demo start + # 👨‍💻 Flyte is ready! Flyte UI is available at http://localhost:30080/console 🚀 🚀 🎉 + # ❇️ Run the following command to export demo environment variables for accessing flytectl + # export FLYTECTL_CONFIG=/home/ubuntu/.flyte/config-sandbox.yaml + # 🐋 Flyte sandbox ships with a Docker registry. Tag and push custom workflow images to localhost:30000 + # 📂 The Minio API is hosted on localhost:30002. Use http://localhost:30080/minio/login for Minio console + +**2. Run workflow locally.** + + +.. code:: shell + + # Step1: Build a virtual environment for developing Flytekit. This will allow your local changes to take effect when the same Python interpreter runs `import flytekit`. + git clone https://github.com/flyteorg/flytekit.git # replace with your own repo + cd flytekit + virtualenv ~/.virtualenvs/flytekit + source ~/.virtualenvs/flytekit/bin/activate + make setup + pip install -e . + + # If you are also developing the plugins, consider the following: + + # Installing Specific Plugins: + # If you wish to only use few plugins, you can install them individually. + # Take [Flytekit BigQuery Plugin](https://github.com/flyteorg/flytekit/tree/master/plugins/flytekit-bigquery#flytekit-bigquery-plugin) for example: + # You have to go to the bigquery plugin folder and install it. + cd plugins/flytekit-bigquery/ + pip install -e . + # Now you can use the bigquery plugin, and the performance is fast. + + # (Optional) Installing All Plugins: + # If you wish to install all available plugins, you can execute the command below. + # However, it's not typically recommended because the current version of plugins does not support + # lazy loading. This can lead to a slowdown in the performance of your Python engine. + cd plugins + pip install -e . + # Now you can use all plugins, but the performance is slow. + + # Step2: Modify the source code for flytekit, then run unit tests and lint. + make lint + make test + + # Step3: Run a hello world sample to test locally + pyflyte run https://raw.githubusercontent.com/flyteorg/flytesnacks/master/examples/basics/basics/hello_world.py hello_world_wf + # Running hello_world_wf() hello world + +**3. Run workflow in sandbox.** + + +Before running your workflow in the sandbox, make sure you're able to successfully run it locally. +To deploy the workflow in the sandbox, you'll need to build a Flytekit image. +Create a Dockerfile in your Flytekit directory with the minimum required configuration to run a task, as shown below. +If your task requires additional components, such as plugins, you may find it useful to refer to the construction of the `officail flitekit image `__ + +.. code:: Dockerfile + + FROM python:3.9-slim-buster + USER root + WORKDIR /root + ENV PYTHONPATH /root + RUN apt-get update && apt-get install build-essential -y + RUN apt-get install git -y + # The following line is an example of how to install your modified plugins. In this case, it demonstrates how to install the 'deck' plugin. + # RUN pip install -U git+https://github.com/Yicheng-Lu-llll/flytekit.git@"demo#egg=flytekitplugins-deck-standard&subdirectory=plugins/flytekit-deck-standard" # replace with your own repo and branch + RUN pip install -U git+https://github.com/Yicheng-Lu-llll/flytekit.git@demo # replace with your own repo and branch + ENV FLYTE_INTERNAL_IMAGE "localhost:30000/flytekit:demo" # replace with your own image name and tag + +The instructions below explain how to build the image, push the image to +the Flyte cluster, and finally submit the workflow. + +.. code:: shell + + # Step1: Ensure you have pushed your changes to the remote repo + # In the flytekit folder + git add . && git commit -s -m "develop" && git push + + # Step2: Build the image + # In the flytekit folder + export FLYTE_INTERNAL_IMAGE="localhost:30000/flytekit:demo" # replace with your own image name and tag + docker build --no-cache -t "${FLYTE_INTERNAL_IMAGE}" -f ./Dockerfile . + + # Step3: Push the image to the Flyte cluster + docker push ${FLYTE_INTERNAL_IMAGE} + + # Step4: Submit a hello world workflow to the Flyte cluster + cd flytesnacks + pyflyte run --image ${FLYTE_INTERNAL_IMAGE} --remote https://raw.githubusercontent.com/flyteorg/flytesnacks/master/examples/basics/basics/hello_world.py hello_world_wf + # Go to http://localhost:30080/console/projects/flytesnacks/domains/development/executions/f5c17e1b5640c4336bf8 to see execution in the console. + +How to setup dev environment for flyteconsole? +********************************************** + +**1. Set up local Flyte cluster.** + +Depending on your needs, refer to one of the following guides to setup up the Flyte cluster: + +- If you do not need to change the backend code, refer to the section on `How to Set Up a Dev Environment for Flytekit? <#how-to-setup-dev-environment-for-flytekit>`__ +- If you need to change the backend code, refer to the section on `How to setup dev environment for flyteidl, flyteadmin, flyteplugins, flytepropeller, datacatalog and flytestdlib? <#how-to-setup-dev-environment-for-flyteidl-flyteadmin-flyteplugins-flytepropeller-datacatalog-and-flytestdlib>`__ + + +**2. Start flyteconsole.** + + +.. code:: shell + + # Step1: Clone the repo and navigate to the Flyteconsole folder + git clone https://github.com/flyteorg/flyteconsole.git + cd flyteconsole + + # Step2: Install Node.js 18. Refer to https://github.com/nodesource/distributions/blob/master/README.md#using-ubuntu-2. + curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - &&\ + sudo apt-get install -y nodejs + + # Step3: Install yarn. Refer to https://classic.yarnpkg.com/lang/en/docs/install/#debian-stable. + curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - + echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list + sudo apt update && sudo apt install yarn + + # Step4: Add environment variables + export BASE_URL=/console + export ADMIN_API_URL=http://localhost:30080 + export DISABLE_AUTH=1 + export ADMIN_API_USE_SSL="http" + + # Step5: Generate SSL certificate + # Note, since we will use HTTP, SSL is not required. However, missing an SSL certificate will cause an error when starting Flyteconsole. + make generate_ssl + + # Step6: Install node packages + yarn install + yarn build:types # It is fine if seeing error `Property 'at' does not exist on type 'string[]'` + yarn run build:prod + + # Step7: Start flyteconsole + yarn start + +**3. Install the Chrome plugin:** `Moesif Origin & CORS Changer `__. + + +We need to disable `CORS `__ to load resources. + +:: + + 1. Activate plugin (toggle to "on") + 2. Open 'Advanced Settings': + 3. set Access-Control-Allow-Credentials: true + +**4. Go to** http://localhost:3000/console/. + + +How to access Flyte UI, minio, postgres, k3s, and endpoints? +************************************************************************* + + +This section presumes a local Flyte cluster is already setup. If it isn't, refer to either: + +- `How to setup dev environment for flytekit? <#how-to-setup-dev-environment-for-flytekit>`__ +- `How to setup dev environment for flyteidl, flyteadmin, flyteplugins, flytepropeller, datacatalog and flytestdlib? <#how-to-setup-dev-environment-for-flyteidl-flyteadmin-flyteplugins-flytepropeller-datacatalog-and-flytestdlib>`__ + + +**1. Access the Flyte UI.** + + +`Flyte UI `__ is a web-based user interface for Flyte that lets you interact with Flyte objects and build directed acyclic graphs (DAGs) for your workflows. + +You can access it via http://localhost:30080/console. + +**2. Access the minio console.** + + +Core Flyte components, such as admin, propeller, and datacatalog, as well as user runtime containers rely on an object store (in this case, minio) to hold files. +During development, you might need to examine files such as `input.pb/output.pb `__, or `deck.html `__ stored in minio. + +Access the minio console at: http://localhost:30080/minio/login. The default credentials are: + +- Username: ``minio`` +- Password: ``miniostorage`` + + +**3. Access the postgres.** + + +FlyteAdmin and datacatalog use postgres to store persistent records, and you can interact with postgres on port ``30001``. Here is an example of using `psql` to connect: + +.. code:: shell + + # Step1: Install the PostgreSQL client. + sudo apt-get update + sudo apt-get install postgresql-client + + # Step2: Connect to the PostgreSQL server. The password is "postgres". + psql -h localhost -p 30001 -U postgres -d flyte + + +**4. Access the k3s dashboard.** + + +Access the k3s dashboard at: http://localhost:30080/kubernetes-dashboard. + +**5. Access the endpoints.** + + +Service endpoints are defined in the `flyteidl` repository under the `service` directory. You can browse them at `here `__. + +For example, the endpoint for the `ListTaskExecutions `__ API is: + +.. code:: shell + + /api/v1/task_executions/{node_execution_id.execution_id.project}/{node_execution_id.execution_id.domain}/{node_execution_id.execution_id.name}/{node_execution_id.node_id} + +You can access this endpoint at: + +.. code:: shell + + # replace with your specific task execution parameters + http://localhost:30080/api/v1/task_executions/flytesnacks/development/fe92c0a8cbf684ad19a8/n0?limit=10000 + + + + + + +🐞 File an issue +================ + +We use `GitHub Issues `__ for issue tracking. The following issue types are available for filing an issue: + +* `Plugin Request `__ +* `Bug Report `__ +* `Documentation Bug/Update Request `__ +* `Core Feature Request `__ +* `Flytectl Feature Request `__ +* `Housekeeping `__ +* `UI Feature Request `__ + +If none of the above fit your requirements, file a `blank `__ issue. +Also, add relevant labels to your issue. For example, if you are filing a Flytekit plugin request, add the ``flytekit`` label. + +For feedback at any point in the contribution process, feel free to reach out to us on `Slack `__. diff --git a/docs/community/index.rst b/docs/community/index.rst new file mode 100644 index 0000000000..c2ee55ae23 --- /dev/null +++ b/docs/community/index.rst @@ -0,0 +1,127 @@ +.. _community: + +########## +Community +########## + +Flyte is an ambitious open source project and would not be possible without an +amazing community. We are a completely open community and strive to treat +every member with respect. You will find the community welcoming and responsive! + +Please join us on: + +.. image:: https://img.shields.io/badge/Slack-Chat-pink?style=for-the-badge + :target: https://slack.flyte.org + :alt: Flyte Slack + +.. image:: https://img.shields.io/badge/Github-Discussion-green?style=for-the-badge + :target: https://github.com/flyteorg/flyte/discussions + :alt: Github Discussion + +.. image:: https://img.shields.io/badge/Twitter-Social-blue?style=for-the-badge + :target: https://twitter.com/flyteorg + :alt: Twitter + +.. image:: https://img.shields.io/badge/LinkedIn-Social-lightblue?style=for-the-badge + :target: https://www.linkedin.com/groups/13962256 + :alt: LinkedIn + + +Open Source Community Meeting +----------------------------- + +When: every other Tuesday, 9:00 AM Pacific Time. +You're welcome to join and learn from other community members sharing their experiences with Flyte or any other technology from the AI ecosystem. +Check out the event details and add it to your `calendar `_, or just pop in! + +.. image:: https://img.shields.io/badge/Join-Zoom-blue?style=for-the-badge + :target: https://www.addevent.com/event/EA7823958 + :alt: Zoom Link + +Office Hours +------------ + +`Book a 30 minutes session `_ with a Flyte maintainer and get your questions answered! + +Schedule your session depending on the topic to secure the availability of a maintainer with expertise in the area: + +- **7:00a.m. PT**: + - Anything flytekit-related + - Flyte releases + - flytepropeller features + - Plugin implementation + - Platform configuration +- **1:00p.m. PT**: + - Flyte deployment, auth +- **9:00p.m. PT**: + - Flytekit-related + - Use cases + - Getting started (workflow onboarding) + - Integrations + + +Newsletter +---------- + +`Join the Flyte mailing list `_ to receive the monthly newsletter + + +Slack guidelines +----------------- + +Flyte strives to build and maintain an open, inclusive, productive and self-governing open source community. In consequence, +we expect all community members to respect the following guidelines: + +Abide by the `LF's Code of Conduct `__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +As a Linux Foundation project, we must enforce the rules that govern professional and positive open source communities. + +Avoid using DMs and @mentions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Whenever possible, post your questions and responses in public channels so other Community Members can benefit from the conversation and outcomes. +Exceptions to this are when you need to share private or sensible information. In such a case, the outcome should still be shared publicly. +Limit the use of @mentions of other Community Members to be considerate of notification noise. + +Make use of threads +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Threads help us keep conversations contained and organized, reducing the time it takes to give you the support you need. + +Thread best practices: + +- Don't break your question into multiple messages. Put everything in one. +- For long questions, write a few sentences in the first message, and put the rest in a thread. +- If there's a code snippet (more than 5 lines of code), put it inside the thread. +- Avoid using the “Also send to channel” feature unless it's really necessary. +- If your question contains multiple questions, make sure to break them into multiple messages, so each could be answered in a separate thread. + + +Do not post the same question across multiple channels +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you consider that question needs to be shared on other channels, ask it once and then indicate explicitly that you're cross-posting. + +If you're having a tough time getting the support you need (or aren't sure where to go!), please DM @David Espejo(he/him) or @Samhita Alla for support. + +Do not solicit members of our Slack +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Flyte Community exists to collaborate with, learn from, and support one another. It is not a space to pitch your products or services directly to our members via public channels, private channels, or direct messages. + +We are excited to have a growing presence from vendors to help answer questions from Community Members as they may arise, but we have a strict 3-strike policy against solicitation: + +- First occurrence: We'll give you a friendly but public reminder that the behavior is inappropriate according to our guidelines. +- Second occurrence: We'll send you a DM warning that any additional violations will result in removal from the community. +- Third occurrence: We'll delete or ban your account. + +We reserve the right to ban users without notice if they are clearly spamming our Community Members. + +If you want to promote a product or service, go to the #shameless-promotion channel and make sure to follow these rules: + +- Don't post more than two promotional posts per week +- Non-relevant topics aren't allowed + +Messages that don't follow these rules will be deleted. + + diff --git a/docs/community/roadmap.rst b/docs/community/roadmap.rst new file mode 100644 index 0000000000..3e6bc3f5ae --- /dev/null +++ b/docs/community/roadmap.rst @@ -0,0 +1,145 @@ +.. _community_roadmap: + +############### +Roadmap +############### + +How the Community Works +======================= +Flyte is actively used in production at multiple companies. We pride ourselves on being extremely customer-focused, and care about providing a high quality customer experience. We therefore always +prioritize stability, reliability, observability and maintainability over raw feature development. + +Features are usually developed in response to specific use cases and user scenarios. That being said, we are proactively thinking about the evolution of the system and how we want to keep adapting to changing requirements. Thus most of our changes reflect future development scenarios, and in +cases where we feel rapid prototyping would enable us to discover potential pitfalls or uncover hidden use cases, we would proactively develop features behind feature flags. + +It is extremely important to let the community know about your use cases, so that we adapt parts of Flyte to meet those requirements. We welcome collaboration and contributions, but please follow our `Contribution Guidelines `_. The quarterly planning meeting is also hosted publicly, please see more below. + + +Milestones and Release Processes +================================ +Flyte consists of many components and services. Each service is independently iterated and coordinated by maintaining backwards compatible contracts using Protobuf messages defined in `FlyteIDL `__. + +Release Cadence +--------------- +We aim to release Flyte quarterly, with the understanding that rather than being tied strictly to the calendar, we aim to have substantial features, improvements, and bug fixes at each quarter. If features slated for a given release are delayed, then the release will be delayed as well. The increased time will also give the Flyte development team more time to beta test each feature and release. + +Versioning Scheme +----------------- +*Please keep in mind the CI work to implement this scheme is still in progress* + +At each quarterly release, major components of Flyte and the Flyte repository itself will be released with an incremented minor version number and the version number will be aligned across those components. The major version number will remain ``1`` for the foreseeable future. That is, if the current version of Flyte is ``1.2.x``, the next release will be ``1.3.0`` for Flyte and the major components. + +After each version is released, merges to master will be assigned beta releases of the next release version. That is, if ``flytepropeller`` version ``v1.2.0`` was just released, the next merge to master will be tagged ``v1.3.0b0``. + +Not strictly forcing a time-constraint on the Flyte release cycle means that if a substantial number of changes is merged, perhaps due to a security issue or just a rapid pace of feature development, we can always bring up the timeline of the release. + +Components with versions aligned +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* Propeller +* Admin +* Console +* datacatalog +* flytectl +* flytesnacks +* Flytekit +* flytekit-java + +The last two we are going to tie together for now, but realize that we may want to unpin in the future. + +Components versioned independently +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* flyteidl +* flytestdlib +* flyteplugins +* flytecopilot + +Helm Charts +^^^^^^^^^^^ +Helm charts deserve a special mention here. Unlike the other components which will have patch versions that differ, the Flyte release version and the Helm chart version will always be identical down to the patch. That is, a Flyte release is a Helm release and vice-versa. + +Release Branches and Patching +----------------------------- +After each minor release, a release branch will be created. There will be no alignment of patch versions across the components. That is, by the end of the ``1.3.x`` release cycle, ``flyteadmin`` may be on ``1.3.8`` and ``flytepropeller`` may be on ``1.3.2``. + +When developing bug fixes, by default we will continue to develop off of master, which will not be the stable branch. After such bug fixes are merged, it will be the responsibility of the developer to ensure that the patches are also applied to prior releases. At the current time, we propose only supporting one release back (two for security patches). That is, if ``flytepropeller`` has a bug fix that results in ``v1.3.0b0`` that patch will be applied to the ``v1.2.x`` release, but not the ``v1.1.x`` release. + +Beta Patch Releases +^^^^^^^^^^^^^^^^^^^ +We also propose that beta patch versions be merged into the release branch when patching prior releases. For example, assuming no patches have yet to be made to the ``v1.2.0`` release, when porting a bug fix that resulted in ``v1.3.0b0`` onto the ``release-v1.2`` branch, the developer can first release ``v1.2.1b0`` for testing into ``release-v1.2`` before releasing the ``v1.2.1`` release. Such beta releases should be made at the discretion of the developer. + +Whether or not a patch version of any of the Flyte components also creates a Flyte patch release shall also be left to the discretion of the developer. + +Documentation Versioning +------------------------ +We also currently have an issue with our documentation versioning. While our readthedocs page does have versioning enabled and we publish the [docs version](https://github.com/flyteorg/flyte/blob/80c098f10334b1c916d1e4274ab9f204152d9d80/rsts/conf.py#L33), all the [intersphinx mappings](https://github.com/flyteorg/flyte/blob/80c098f10334b1c916d1e4274ab9f204152d9d80/rsts/conf.py#L219) just point to `latest`. Keep in mind that this mapping not only exists in this `flyte` repo, but also in all the other repos that that mapping points to. That is, to maintain an accurate mapping of different versions of documentation, we'll need to update the mapping in all the repos. + +To remediate this, we propose the following: + +* Documentation should be pinned only to Major.Minor on all the repos that have their versions "aligned". + + * This means that as we release patch versions of Admin, Propeller, etc., if we're on v1.1 for instance, as Admin code/auto-generated documentation changes, the v1.1 listing of readthedocs will automatically pick it up. +* Repos that are not aligned will just default to the "latest" documentation version. + +Planning Process +================ + +Quarterly Planning +------------------ +Members of the community should feel free to join these! Core members of the Flyte team will come prepared with general initiatives in mind. We will use these meetings to prioritize these ideas, assess community interest and impact, and decide what goes into the GitHub milestone for the next release. Members of the community looking to contribute should also join. Please look for this meeting invite on the calendar - it may not be set up as a recurring meeting simply because it will likely change by a few days each quarter. + +Change Management +------------------ +To ensure that changes are trackable and the history is explainable, we use a slightly cumbersome but helpful process, with the following immediate goals: +- Every PR is associated with an issue (automatic searchable documentation) +- Large PRs are associated with Proposals +- Every major change is associated with documentation +- Owner files exist for all repositories + +Issue Lifecycle +--------------- +- Incoming issues are tagged automatically as untriaged. +- Periodically, members of the Flyte community will meet to triage incoming issues. We aim to do this on a weekly basis. +- During this meeting we'll attempt to assign each issue to a milestone. Some issues however will need to be investigated before we can fully assess. +- Once an issue is assigned to a milestone, this means we are committed to delivering it that release. This means the burden for adding something to the milestone is relatively high. Issues that slip should only slip for good reason. + +Browse Features and Issues +============================ + +Issues by Theme +---------------- + ++-------------+----------------------------------------------------------------+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ +| Theme | Description | Open Issues | Comment | ++-------------+----------------------------------------------------------------+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ +| Bugs | Currently known and open bugs. | `Bugs `_ | We are always working on bugs. Open a new one `here `_. | ++-------------+----------------------------------------------------------------+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ +| Security | Issues related to security enhancements. | `Security issues `_ | | ++-------------+----------------------------------------------------------------+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ +| Docs | All issues open with our documentation | `Docs issues `_ | Starting Feb 2021, we will be completely overhauling our docs. Feedback appreciated! | ++-------------+----------------------------------------------------------------+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ +| Features | All new features in development | `Features issues `_ | | ++-------------+----------------------------------------------------------------+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ +| Plugins | New capabilities and plugins that are built into Flyte. | `Plugins issues `_ | This is one of the best places to get started contributing to Flyte. Issues with both | +| | These could be hosted services, K8s native execution, etc. | | `plugins` and `flytekit` labels refer to purely client-side plugins and are the fastest to contribute to. | ++-------------+----------------------------------------------------------------+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ +| Scale | These issues deal with performance, reliability and | `Scale issues `_ | We are always working on these issues and we would love to hear feedback about what you | +| | scalability of Flyte | | would want to change or what we should prioritize. | ++-------------+----------------------------------------------------------------+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ +| Contribute | If you are looking to contribute and want a great first issue, | `Contribute issues `_ | These are the best issues to get started with. | +| | check out these issues | | | ++-------------+----------------------------------------------------------------+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ + + +Issues by Components +--------------------- + ++---------------+---------------------------------------+------------------------------------------------------------------------+ +| Theme | Description | Open Issues | ++===============+=======================================+========================================================================+ +| Flyte Console | Issues concerning our web UI. | `Flyte Console issues `_ | ++---------------+---------------------------------------+------------------------------------------------------------------------+ +| Flytectl | Issues concerning our standalone CLI. | `Flytectl issues `_ | ++---------------+---------------------------------------+------------------------------------------------------------------------+ + +For an overview of what we're currently working on, check out our `live roadmap `__. + diff --git a/docs/community/troubleshoot.rst b/docs/community/troubleshoot.rst new file mode 100644 index 0000000000..b4f6c271d4 --- /dev/null +++ b/docs/community/troubleshoot.rst @@ -0,0 +1,135 @@ +.. _troubleshoot: + +===================== +Troubleshooting Guide +===================== + +.. tags:: Troubleshoot, Basic + +The content in this section will help Flyte users isolate the most probable causes for some of the common issues that could arise while getting started with the project. + +Before getting started, collect the following information from the underlying infrastructure: + +- Capture the ``Status`` column from the output of: + +.. prompt:: bash $ + + $ kubectl describe pod -n + +Where will typically correspond to the node execution string that you can find in the UI. + +- Pay close attention to the `Events` section in the output. +- Also, collect the logs from the Pod: + +.. prompt:: bash $ + + $ kubectl logs pods -n + +Where will typically correspond to the Flyte -, e.g. flytesnacks-development. + +Depending on the contents of the logs or the `Events`, you can try different things: + +Debugging common execution errors +---------------------------------- + +``message: '0/1 nodes are available: 1 Insufficient cpu. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod.'`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This issue is more common on MacOS devices. Make sure that your Docker daemon has allocated a minimum of 4 CPU cores and 3GB of RAM + +``terminated with exit code (137). Reason [OOMKilled]`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- For single binary environment deployed with Helm chart, make sure you are using `the most recent charts `_ + +- For EKS deployments, you cand adjust resource limits and requests in the `inline `_ section of the ``eks-production.yaml`` file. Example: + +.. code-block:: yaml + + inline: + task_resources: + defaults: + cpu: 100m + memory: 100Mi + storage: 100Mi + limits: + memory: 1Gi + +- Also, the default container resource limits are can be overridden from the task itself: + +.. code-block:: python + + from flytekit import Resources, task + @task(limits=Resources(mem="256Mi") + def your_task(... + +``Error: ImagePullBackOff`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- If your environment requires the use of a network proxy use the ``--env`` option when starting the sandbox and pass the proxy configuration: + +.. prompt:: bash $ + + $ flytectl demo start --env HTTP_PROXY= + +- If you're building a custom Docker image, make sure to use a tag other than ``latest``. Otherwise, the Kubernetes default pull policy will be changed from ``IfNotPresent`` to ``Always``, forcing an image pull with every Pod deployment. + +Issues running workloads +------------------------- + +``OPENSSL_internal:WRONG_VERSION_NUMBER`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- For ``flyte-binary``: make sure that the endpoint name you have set in your ``config.yaml`` file, is included in the DNS names of the SSL certificate installed (be it self signed or issued by a Certificate Authority) +- For ``sandbox``: verify the ``FLYTECTL_CONFIG`` environment variable has the correct value by running: + +.. prompt:: bash $ + + $ export FLYTECTL_CONFIG=~/.flyte/config-sandbox.yaml + +``ModuleNotFoundError`` +^^^^^^^^^^^^^^^^^^^^^^^ + +- If you're using a custom container image and using Docker, make sure your ``Dockerfile`` is located at the same level of the ``flyte`` directory and that there is an empty ``__init__.py`` file in your project's folder : + +.. prompt:: bash $ + + myflyteapp + ├── Dockerfile + ├── docker_build_and_tag.sh + ├── flyte + │ ├── __init__.py + │ └── workflows + │ ├── __init__.py + │ └── example.py + └── requirements.txt + +``An error occurred (AccessDenied) when calling the PutObject operation`` in an EKS deployment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Make sure that the Kubernetes service account Flyte is using has the annotation that refers to the IAM Role is connected to: + +.. prompt:: bash $ + + $ kubectl describe sa -n + +Example output: + +.. prompt:: bash $ + + Name: + Namespace: flyte + Labels: app.kubernetes.io/managed-by=eksctl + Annotations: eks.amazonaws.com/role-arn: arn:aws:iam:::role/flyte-system-role + Image pull secrets: + Mountable secrets: + Tokens: + Events: + +- Otherwise, obtain your IAM role's ARN and manually annotate the service account: + +.. prompt:: bash $ + + $ kubectl annotate serviceaccount -n eks.amazonaws.com/role-arn=arn:aws:iam::xxxx:role/ + +- Refer to this community-maintained `guides `_ for further information about Flyte deployment on EKS diff --git a/docs/concepts/admin.rst b/docs/concepts/admin.rst new file mode 100644 index 0000000000..4e6ee67a8e --- /dev/null +++ b/docs/concepts/admin.rst @@ -0,0 +1,500 @@ +.. _divedeep-admin: + +########## +FlyteAdmin +########## + +.. tags:: Advanced, Design + +Admin Structure +=============== + +FlyteAdmin serves as the main Flyte API to process all client requests to the system. Clients include the FlyteConsole, which calls: + +1. FlyteAdmin to list the workflows, get execution details, etc. +2. Flytekit, which in turn calls FlyteAdmin to register, launch workflows, etc. + +Below, we'll dive into each component defined in admin in more detail. + +RPC +--- + +FlyteAdmin uses the `grpc-gateway `__ library to serve incoming gRPC and HTTP requests with identical handlers. +Refer to the admin service :std:ref:`definition ` for a detailed API overview, including request and response entities. +The RPC handlers are thin shims that enforce request structure validation and call out to the appropriate :ref:`manager ` methods to process requests. + +You can find a detailed explanation of the service in the :ref:`admin service ` page. + +.. _divedeep-admin-manager: + +Managers +-------- + +The Admin API is broken up into entities: + +- Executions +- Launch plans +- Node Executions +- Projects (and their respective domains) +- Task Executions +- Tasks +- Workflows + +Each API entity has an entity manager in FlyteAdmin responsible for implementing business logic for the entity. +Entity managers handle full validation of creating, updating and getting requests and +data persistence in the backing store (see the :ref:`divedeep-admin-repository` section). + + +Additional Components ++++++++++++++++++++++ + +The managers utilize additional components to process requests. These additional components include: + +- :ref:`workflow engine `: compiles workflows and launches workflow executions from launch plans. +- :ref:`data ` (remote cloud storage): offloads data blobs to the configured cloud provider. +- :ref:`runtime `: loads values from a config file to assign task resources, initialization values, execution queues, and more. +- :ref:`async processes `: provides functions to schedule and execute the workflows as well as enqueue and trigger notifications. + +.. _divedeep-admin-repository: + +Repository +---------- +Serialized entities (tasks, workflows, launch plans) and executions (workflow-, node- and task-) are stored as protos defined +`here `__. +We use the excellent `gorm `__ library to interface with our database, which currently supports a Postgres +implementation. You can find the actual code for issuing queries with gorm in the +`gormimpl `__ directory. + +Models +++++++ +Database models are defined in the `models `__ directory and correspond 1:1 with the database tables [0]_. + +The full set of database tables includes: + +- executions +- execution_events +- launch_plans +- node_executions +- node_execution_events +- tasks +- task_executions +- workflows + +These database models inherit primary keys and indexes as defined in the corresponding `models `__ file. + +The repositories code also includes `transformers `__. +These convert entities from the database format to a response format for the external API. +If you change either of these structures, you must change the corresponding transformers too. + + +.. _divedeep-admin-async: + +Component Details +================= + +This section dives into the details of each top-level directory defined in ``pkg/``. + +Asynchronous Components +----------------------- + +Notifications and schedules are handled by async routines that are responsible for enqueuing and subsequently processing dequeued messages. + +FlyteAdmin uses the `gizmo toolkit `__ to abstract queueing implementation. Gizmo's +`pubsub `__ library offers implementations for Amazon SNS/SQS, Google Pubsub, Kafka topics, and publishing over HTTP. + +For the sandbox development, no-op implementations of the notifications and schedule handlers are used to remove external cloud dependencies. + + +Common +------ + +As the name implies, ``common`` houses shared components used across different FlyteAdmin components in a single, top-level directory to avoid cyclic dependencies. These components include execution naming and phase utils, query filter definitions, query sorting definitions, and named constants. + +.. _divedeep-admin-data: + +Data +----- + +Data interfaces are primarily handled by the `storage `__ library implemented in ``flytestdlib``. However, neither this nor the underlying `stow `__ library expose `HEAD `__ support. Hence, the data package in admin exists as the layer responsible for additional, remote data operations. + +Errors +------ + +The errors directory contains centrally defined errors that are designed for compatibility with gRPC statuses. + +.. _divedeep-admin-config: + +Runtime +------- +Values specific to the FlyteAdmin application, including task, workflow registration, and execution are configured in the `runtime `__ directory. These interfaces expose values configured in the ``flyteadmin`` top-level key in the application config. + +.. _divedeep-admin-workflowengine: + +Workflow engine +---------------- + +This directory contains the interfaces to build and execute workflows leveraging FlytePropeller compiler and client components. + +.. [0] Given the unique naming constraints, some models are redefined in `migration_models `__ to guarantee unique index values. + +.. _divedeep-admin-service: + + +FlyteAdmin Service Background +============================= + +Entities +--------- + +The :std:ref:`admin service definition ` defines REST operations for the entities that +FlyteAdmin administers. + +As a refresher, the primary :ref:`entities ` across Flyte maps to FlyteAdmin entities. + +Static entities ++++++++++++++++ + +These include: + +- Workflows +- Tasks +- Launch Plans + +Permitted operations include: + +- Create +- Get +- List + +The above entities are designated by an :std:ref:`identifier ` +that consists of a project, domain, name, and version specification. These entities are, for the most part, immutable. To update one of these entities, the updated +version must be re-registered with a unique and new version identifier attribute. + +One caveat is that the launch plan can toggle between :std:ref:`ACTIVE and INACTIVE ` states. +At a given point in time, only one launch plan version across a shared {Project, Domain, Name} specification can be active. The state affects the scheduled launch plans only. +An inactive launch plan can be used to launch individual executions. However, only an active launch plan runs on a schedule (given it has a schedule defined). + + +Static entities metadata (Named Entities) ++++++++++++++++++++++++++++++++++++++++++ + +A :std:ref:`named entity ` includes metadata for one of the above entities +(workflow, task or launch plan) across versions. It also includes a resource type (workflow, task or launch plan) and an +:std:ref:`id ` which is composed of project, domain and name. +The named entity also includes metadata, which are mutable attributes about the referenced entity. + +This metadata includes: + +- Description: a human-readable description for the Named Entity collection. +- State (workflows only): this determines whether the workflow is shown on the overview list of workflows scoped by project and domain. + +Permitted operations include: + +- Create +- Update +- Get +- List + + +Execution entities +++++++++++++++++++ + +These include: + +- (Workflow) executions +- Node executions +- Task executions + +Permitted operations include: + +- Create +- Get +- List + +After an execution begins, FlytePropeller monitors the execution and sends the events which the admin uses to update the above executions. + +These :std:ref:`events ` include + +- WorkflowExecutionEvent +- NodeExecutionEvent +- TaskExecutionEvent + +and contain information about respective phase transitions, phase transition time and optional output data if the event concerns a terminal phase change. + +These events provide the **only** way to update an execution. No raw update endpoint exists. + +To track the lifecycle of an execution, admin and store attributes such as `duration` and `timestamp` at which an execution transitioned to running and end time are used. + +For debugging purposes, admin also stores Workflow and Node execution events in its database, but does not currently expose them through an API. Because array tasks can yield many executions, admin does **not** store TaskExecutionEvents. + + +Platform entities ++++++++++++++++++ +Projects: Like named entities, projects have mutable metadata such as human-readable names and descriptions, in addition to their unique string ids. + +Permitted project operations include: + +- Register +- List + +.. _divedeep-admin-matchable-resources: + +Matchable resources ++++++++++++++++++++ + +A thorough background on :ref:`matchable resources ` explains +their purpose and application logic. As a summary, these are used to override system level defaults for Kubernetes cluster +resource management, default execution values, and more across different levels of specificity. + +These entities consist of: + +- ProjectDomainAttributes +- WorkflowAttributes + +``ProjectDomainAttributes`` configure customizable overrides at the project and domain level, and ``WorkflowAttributes`` configure customizable overrides at the project, domain and workflow level. + +Permitted attribute operations include: + +- Update (implicitly creates if there is no existing override) +- Get +- Delete + + +Defaults +-------- + +Task resource defaults +++++++++++++++++++++++ + +User-facing documentation on configuring task resource requests and limits can be found in :std:ref:`cookbook:customizing task resources`. + +As a system administrator you may want to define default task resource requests and limits across your Flyte deployment. +This can be done through the flyteadmin config. + +**Default** values get injected as the task requests and limits when a task definition omits a specific resource. +**Limit** values are only used as validation. Neither a task request nor limit can exceed the limit for a resource type. + + +Using the Admin Service +----------------------- + +Adding request filters +++++++++++++++++++++++ + +We use `gRPC Gateway `_ to reverse proxy HTTP requests into gRPC. +While this allows for a single implementation for both HTTP and gRPC, an important limitation is that fields mapped to the path pattern cannot be +repeated and must have a primitive (non-message) type. Unfortunately this means that repeated string filters cannot use a proper protobuf message. Instead, they use +the internal syntax shown below:: + + func(field,value) or func(field, value) + +For example, multiple filters would be appended to an http request like:: + + ?filters=ne(version, TheWorst)+eq(workflow.name, workflow) + +Timestamp fields use the ``RFC3339Nano`` spec (For example: "2006-01-02T15:04:05.999999999Z07:00") + +The fully supported set of filter functions are + +- contains +- gt (greater than) +- gte (greter than or equal to) +- lt (less than) +- lte (less than or equal to) +- eq (equal) +- ne (not equal) +- value_in (for repeated sets of values) + +"value_in" is a special case where multiple values are passed to the filter expression. For example:: + + value_in(phase, RUNNING;SUCCEEDED;FAILED) + +.. note:: + If you're issuing your requests over http(s), be sure to URL encode the ";" semicolon using ``%3B`` like so: ``value_in(phase, RUNNING%3BSUCCEEDED%3BFAILED)`` + +Filterable fields vary based on entity types: + +- Task + + - project + - domain + - name + - version + - created_at + +- Workflow + + - project + - domain + - name + - version + - created_at + +- Launch plans + + - project + - domain + - name + - version + - created_at + - updated_at + - workflows.{any workflow field above} (for example: workflow.domain) + - state (you must use the integer enum, for example: 1) + - States are defined in :std:ref:`launchplanstate `. + +- Named Entity Metadata + + - state (you must use the integer enum, for example: 1) + - States are defined in :std:ref:`namedentitystate `. + +- Executions (Workflow executions) + + - project + - domain + - name + - workflow.{any workflow field above} (for example: workflow.domain) + - launch_plan.{any launch plan field above} (for example: launch_plan.name) + - phase (you must use the upper-cased string name, for example: ``RUNNING``) + - Phases are defined in :std:ref:`workflowexecution.phase `. + - execution_created_at + - execution_updated_at + - duration (in seconds) + - mode (you must use the integer enum, for example: 1) + - Modes are defined in :std:ref:`executionmode `. + - user (authenticated user or role from flytekit config) + +- Node Executions + + - node_id + - execution.{any execution field above} (for example: execution.domain) + - phase (you must use the upper-cased string name, for example: ``QUEUED``) + - Phases are defined in :std:ref:`nodeexecution.phase `. + - started_at + - node_execution_created_at + - node_execution_updated_at + - duration (in seconds) + +- Task Executions + + - retry_attempt + - task.{any task field above} (for example: task.version) + - execution.{any execution field above} (for example: execution.domain) + - node_execution.{any node execution field above} (for example: node_execution.phase) + - phase (you must use the upper-cased string name, for example: ``SUCCEEDED``) + - Phases are defined in :std:ref:`taskexecution.phase `. + - started_at + - task_execution_created_at + - task_execution_updated_at + - duration (in seconds) + +Putting It All Together +----------------------- + +If you wish to query specific executions that were launched using a specific launch plan for a workflow with specific attributes, use: + +:: + + gte(duration, 100)+value_in(phase,RUNNING;SUCCEEDED;FAILED)+eq(lauch_plan.project, foo) + +eq(launch_plan.domain, bar)+eq(launch_plan.name, baz) + +eq(launch_plan.version, 1234) + +lte(workflow.created_at,2018-11-29T17:34:05.000000000Z07:00) + + + +Adding sorting to requests +++++++++++++++++++++++++++ + +Only a subset of fields are supported for sorting list queries. The explicit list is shown below: + +- ListTasks + + - project + - domain + - name + - version + - created_at + +- ListTaskIds + + - project + - domain + +- ListWorkflows + + - project + - domain + - name + - version + - created_at + +- ListWorkflowIds + + - project + - domain + +- ListLaunchPlans + + - project + - domain + - name + - version + - created_at + - updated_at + - state (you must use the integer enum, for example: 1) + - States are defined in :std:ref:`launchplanstate `. + +- ListWorkflowIds + + - project + - domain + +- ListExecutions + + - project + - domain + - name + - phase (you must use the upper-cased string name, for example: ``RUNNING``) + - Phases are defined in :std:ref:`workflowexecution.phase `. + - execution_created_at + - execution_updated_at + - duration (in seconds) + - mode (you must use the integer enum, for example: 1) + - Modes are defined :std:ref:`execution.proto `. + +- ListNodeExecutions + + - node_id + - retry_attempt + - phase (you must use the upper-cased string name, for example: ``QUEUED``) + - Phases are defined in :std:ref:`nodeexecution.phase `. + - started_at + - node_execution_created_at + - node_execution_updated_at + - duration (in seconds) + +- ListTaskExecutions + + - retry_attempt + - phase (you must use the upper-cased string name, for example: ``SUCCEEDED``) + - Phases are defined in :std:ref:`taskexecution.phase `. + - started_at + - task_execution_created_at + - task_execution_updated_at + - duration (in seconds) + +Sorting syntax +-------------- + +Adding sorting to a request requires specifying the ``key``. For example: The attribute you wish to sort on. Sorting can also optionally specify the direction (one of ``ASCENDING`` or ``DESCENDING``) where ``DESCENDING`` is the default. + +Example sorting HTTP parameter: + +:: + + sort_by.key=created_at&sort_by.direction=DESCENDING + +Alternatively, since ``DESCENDING`` is the default sorting direction, the above could be written as + +:: + + sort_by.key=created_at diff --git a/docs/concepts/architecture.rst b/docs/concepts/architecture.rst new file mode 100644 index 0000000000..6727bd61db --- /dev/null +++ b/docs/concepts/architecture.rst @@ -0,0 +1,121 @@ +.. _divedeep-architecture-overview: + +###################### +Component Architecture +###################### + +.. tags:: Advanced, Glossary, Design + +This document aims to demystify how Flyte's major components ``Flyteidl``, ``Flytekit``, ``Flytectl``, ``FlyteConsole``, ``FlyteAdmin``, ``FlytePropeller``, and ``FlytePlugins`` fit together at a high level. + +FlyteIDL +======== + +In Flyte, entities like "Workflows", "Tasks", "Launch Plans", and "Schedules" are recognized by multiple system components. For components to communicate effectively, they need a shared understanding about the structure of these entities. + +Flyteidl (Interface Definition Language) is where shared Flyte entities are defined. It also defines the RPC service definition for the :std:ref:`core Flyte API `. + +Flyteidl uses the `protobuf `_ schema to describe entities. Clients are generated for Python, Golang, and JavaScript and imported by Flyte components. + + +Planes +====== + +Flyte components are separated into 3 logical planes. The planes are summarized and explained in detail below. The goal is that these planes can be replaced by alternate implementations. + ++-------------------+---------------------------------------------------------------------------------------------------------------+ +| **User Plane** | The User Plane consists of all user tools that assist in interacting with the core Flyte API. | +| | These tools include the FlyteConsole, Flytekit, and Flytectl. | ++-------------------+---------------------------------------------------------------------------------------------------------------+ +| **Control Plane** | The Control Plane implements the core Flyte API. | +| | It serves all client requests coming from the User Plane. | +| | It stores information such as current and past running workflows, and provides that information upon request. | +| | It also accepts requests to execute workflows, but offloads the work to the Data Plane. | ++-------------------+---------------------------------------------------------------------------------------------------------------+ +| **Data Plane** | The sole responsibility of the the Data Plane is to fulfill workflows. | +| | It accepts workflow requests from the Control Plane and guides the workflow to completion, | +| | launching tasks on a cluster of machines as necessary based on the workflow graph. | +| | It sends status events back to the control plane so the information can be stored and surfaced to end-users. | ++-------------------+---------------------------------------------------------------------------------------------------------------+ + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/concepts/architecture/flyte-logical-architecture.png + +User Plane +---------- + +In Flyte, workflows are represented as a Directed Acyclic Graph (DAG) of tasks. While this representation is logical for services, managing workflow DAGs in this format is a tedious exercise for humans. The Flyte User Plane provides tools to create, manage, and visualize workflows in a format that is easily digestible to the users. + +These tools include: + +Flytekit + Flytekit is an SDK that helps users design new workflows using the Python programming language. It can parse the Python code, compile it into a valid Workflow DAG, and submit it to Flyte for execution. + +FlyteConsole + FlyteConsole provides the Web interface for Flyte. Users and administrators can use the console to view workflows, launch plans, schedules, tasks, and individual task executions. The console provides tools to visualize workflows, and surfaces relevant logs for debugging failed tasks. + +Flytectl + Flytectl provides interactive access to Flyte to launch and access workflows via terminal. + + +Control Plane +------------- + +The Control Plane supports the core REST/gRPC API defined in Flyteidl. User Plane tools like FlyteConsole and Flytekit contact the control plane on behalf of users to store and retrieve information. + +Currently, the entire control plane is handled by a single service called **FlyteAdmin**. + +FlyteAdmin is stateless. It processes requests to create entities like tasks, workflows, and schedules by persisting data in a relational database. + +While FlyteAdmin serves the Workflow Execution API, it does not itself execute workflows. To launch workflow executions, FlyteAdmin sends the workflow DAG to the DataPlane. For added scalability and fault-tolerance, FlyteAdmin can be configured to load-balance workflows across multiple isolated data-plane clusters. + + +Data Plane +---------- + +The Data Plane is the engine that accepts DAGs, and fulfills workflow executions by launching tasks in the order defined by the graph. Requests to the Data Plane generally come via the control plane, and not from end-users. + +In order to support compute-intensive workflows at massive scale, the Data Plane needs to launch containers on a cluster of machines. The current implementation leverages `Kubernetes `_ for cluster management. + +Unlike the user-facing Control Plane, the Data Plane does not expose a traditional REST/gRPC API. To launch an execution in the Data Plane, you create a “flyteworkflow” resource in Kubernetes. +A “flyteworkflow” is a Kubernetes `Custom Resource `_ (CRD) created by our team. This custom resource represents the Flyte workflow DAG. + +The core state machine that processes flyteworkflows is the worker known as **FlytePropeller**. + +FlytePropeller leverages the Kubernetes `operator pattern `_. It polls the Kubernetes API, looking for newly created flyteworkflow resources. FlytePropeller understands the workflow DAG, and launches the appropriate Kubernetes pods as needed to complete tasks. It periodically checks for completed tasks, launching downstream tasks until the workflow is complete. + +**Plugins** + +Each task in a flyteworkflow DAG has a specified **type**. The logic for fulfilling a task is determined by its task type. +In the basic case, FlytePropeller launches a single Kubernetes pod to fulfill a task. +Complex task types require workloads to be distributed across hundreds of pods. + +The type-specific task logic is separated into isolated code modules known as **plugins**. +Each task type has an associated plugin that is responsible for handling tasks of its type. +For each task in a workflow, FlytePropeller activates the appropriate plugin based on the task type in order to fulfill the task. + +The Flyte team has pre-built plugins for Hive, Spark, AWS Batch, and :ref:`more `. +To support new use-cases, developers can create their own plugins and bundle them in their FlytePropeller deployment. + +Component Code Architecture +=========================== + +- :ref:`FlytePropeller ` +- :ref:`Flyte Native Scheduler ` + +Component Code References +========================= + +- `FlyteAdmin `__ +- `FlytePropeller `__ +- `DataCatalog `__ +- `FlytePlugins `__ +- `Flyte Native Scheduler `__ + + +.. toctree:: + :maxdepth: 1 + :name: component code architecture + :hidden: + + component_architecture/flytepropeller_architecture + component_architecture/native_scheduler_architecture diff --git a/docs/concepts/basics.rst b/docs/concepts/basics.rst new file mode 100644 index 0000000000..e36f0e55cc --- /dev/null +++ b/docs/concepts/basics.rst @@ -0,0 +1,24 @@ +.. _divedeep: + +############# +Concepts +############# + +.. toctree:: + :maxdepth: 1 + :name: Core Concepts + + tasks + workflows + nodes + launchplans + schedules + registration + executions + state_machine + execution_timeline + data_management + flyte_console + catalog + versioning + workflow_lifecycle diff --git a/docs/concepts/catalog.rst b/docs/concepts/catalog.rst new file mode 100644 index 0000000000..8b092e73c0 --- /dev/null +++ b/docs/concepts/catalog.rst @@ -0,0 +1,63 @@ +.. _divedeep-catalog: + +What is Data Catalog? +===================== + +.. tags:: Advanced, Design + +`DataCatalog `__ is a service to index parameterized, strongly-typed data artifacts across revisions. It allows clients to query artifacts based on meta information and tags. + + +How Flyte Memoizes Task Executions on Data Catalog +-------------------------------------------------- + +Flyte `memoizes task executions` by creating artifacts in DataCatalog and associating meta information regarding the execution with the artifact. Let's walk through what happens when a task execution is cached on DataCatalog. + +Every task instance is represented as a DataSet: + +.. code-block:: javascript + + Dataset { + project: Flyte project the task was registered in + domain: Flyte domain for the task execution + name: flyte_task- + version: -- + } + +Every task execution is represented as an Artifact in the Dataset above: + +.. code-block:: javascript + + Artifact { + id: uuid + Metadata: [executionName, executionVersion] + ArtifactData: [List of ArtifactData] + } + + + ArtifactData { + Name: + value: + } + +To retrieve the Artifact, tag the Artifact with a hash of the input values for the memoized task execution: + +.. code-block:: javascript + + ArtifactTag { + Name: flyte_cached- + } + +When caching an execution, FlytePropeller will: + +1. Create a dataset for the task. +2. Create an artifact that represents the execution, along with the artifact data that represents the execution output. +3. Tag the artifact with a unique hash of the input values. + +To ensure that the task execution is memoized, Flyte Propeller will: + +1. Compute the tag by computing the hash of the input. +2. Check if a tagged artifact exists with that hash. + + - If it exists, we have a cache hit and the Propeller can skip the task execution. + - If an artifact is not associated with the tag, Propeller needs to run the task. diff --git a/docs/concepts/component_architecture/flytepropeller_architecture.rst b/docs/concepts/component_architecture/flytepropeller_architecture.rst new file mode 100644 index 0000000000..a04f6dbe4d --- /dev/null +++ b/docs/concepts/component_architecture/flytepropeller_architecture.rst @@ -0,0 +1,81 @@ +.. _flytepropeller-architecture: + +########################### +FlytePropeller Architecture +########################### + +.. tags:: Advanced, Design + +.. note:: + In the frame of this document, we use the term “workflow” to describe the single execution of a workflow definition. + +Introduction +============ + +A Flyte :ref:`workflow ` is represented as a Directed Acyclic Graph (DAG) of interconnected Nodes. Flyte supports a robust collection of Node types to ensure diverse functionality. + +- ``TaskNodes`` support a plugin system to externally add system integrations. +- Control flow can be altered during runtime using ``BranchNodes``, which prune downstream evaluation paths based on input. +- ``DynamicNodes`` add nodes to the DAG. +- ``WorkflowNodes`` allow embedding workflows within each other. + +FlytePropeller is responsible for scheduling and tracking execution of Flyte workflows. It is implemented using a K8s controller and adheres to the established K8s design principles. In this scheme, resources are periodically evaluated and the goal is to transition from the observed state to a requested state. + +In our case, workflows are the resources and they are iteratively evaluated to transition from the current state to success. During each loop, the current workflow state is established as the phase of workflow nodes and subsequent tasks, and FlytePropeller performs operations to transition this state to success. The operations may include scheduling (or rescheduling) node executions, evaluating dynamic or branch nodes, etc. These design decisions ensure that FlytePropeller can scale to manage a large number of concurrent workflows without performance degradation. + +This document attempts to break down the FlytePropeller architecture by tracking workflow life cycle through each internal component. Below is a high-level illustration of the FlytePropeller architecture and a flow chart of each component's responsibilities during FlyteWorkflow execution. + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/concepts/architecture/flytepropeller_architecture.png + +Components +========== + +FlyteWorkflow CRD / K8s Integration +----------------------------------- + +Workflows in Flyte are maintained as Custom Resource Definitions (CRDs) in Kubernetes, which are stored in the backing etcd cluster. Each execution of a workflow definition results in the creation of a new FlyteWorkflow CR (Custom Resource) which maintains a state for the entirety of processing. CRDs provide variable definitions to describe both resource specifications (spec) and status' (status). The FlyteWorkflow CRD uses the spec subsection to detail the workflow DAG, embodying node dependencies, etc. The status subsection tracks workflow metadata including overall workflow status, node/task phases, status/phase transition timestamps, etc. + +K8s exposes a powerful controller/operator API that enables entities to track creation/updates over a specific resource type. FlytePropeller uses this API to track FlyteWorkflows, meaning every time an instance of the FlyteWorkflow CR is created/updated, the FlytePropeller instance is notified. FlyteAdmin is the common entry point, where initialization of FlyteWorkflow CRs may be triggered by user workflow definition executions, automatic relaunches, or periodically scheduled workflow definition executions. However, it is conceivable to manually create FlyteWorkflow CRs, but this will have limited visibility and usability. + +WorkQueue/WorkerPool +---------------------- + +FlytePropeller supports concurrent execution of multiple, unique workflows using a WorkQueue and WorkerPool. + +The WorkQueue is a FIFO queue storing workflow ID strings that require a lookup to retrieve the FlyteWorkflow CR to ensure up-to-date status. A workflow may be added to the queue in a variety of circumstances: + +#. A new FlyteWorkflow CR is created or an existing instance is updated +#. The K8s Informer resyncs the FlyteWorkflow periodically (necessary to detect workflow timeouts and ensure liveness) +#. A FlytePropeller worker experiences an error during a processing loop +#. The WorkflowExecutor observes a completed downstream node +#. A NodeHandler observes state change and explicitly enqueues its owner (For example, K8s pod informer observes completion of a task) + +The WorkerPool is implemented as a collection of goroutines, one for each worker. Using this lightweight construct, FlytePropeller can scale to 1000s of workers on a single CPU. Workers continually poll the WorkQueue for workflows. On success, the workflow is executed (passed to WorkflowExecutor). + +WorkflowExecutor +---------------- + +The WorkflowExecutor is responsible for handling high-level workflow operations. This includes maintaining the workflow phase (for example: running, failing, succeeded, etc.) according to the underlying node phases and administering pending cleanup operations. For example, aborting existing node evaluations during workflow failures or removing FlyteWorkflow CRD finalizers on completion to ensure the CR is deleted. Additionally, at the conclusion of each evaluation round, the WorkflowExecutor updates the FlyteWorkflow CR with updated metadata fields to track the status between evaluation iterations. + +NodeExecutor +------------ + +The NodeExecutor is executed on a single node, beginning with the workflow's start node. It traverses the workflow using a visitor pattern with a modified depth-first search (DFS), evaluating each node along the path. A few examples of node evaluation based on phase: successful nodes are skipped, unevaluated nodes are queued for processing, and failed nodes may be reattempted up to a configurable threshold. There are many configurable parameters to tune evaluation criteria including max parallelism which restricts the number of nodes which may be scheduled concurrently. Additionally, nodes may be retried to ensure recoverability on failure. + +The NodeExecutor is also responsible for linking data readers/writers to facilitate data transfer between node executions. The data transfer process occurs automatically within Flyte, using efficient K8s events rather than a polling listener pattern which incurs more overhead. Relatively small amounts of data may be passed between nodes inline, but it is more common to pass data URLs to backing storage. A component of this is writing to and checking the data cache, which facilitates the reuse of previously completed evaluations. + +NodeHandlers +------------ + +FlytePropeller includes a robust collection of NodeHandlers to support diverse evaluation of the workflow DAG: + +* **TaskHandler (Plugins)**: These are responsible for executing plugin specific tasks. This may include contacting FlyteAdmin to schedule K8s pod to perform work, calling a web API to begin/track evaluation, and much more. The plugin paradigm exposes an extensible interface for adding functionality to Flyte workflows. +* **DynamicHandler**: Flyte workflow CRs are initialized using a DAG compiled during the registration process. The numerous benefits of this approach are beyond the scope of this document. However, there are situations where the complete DAG is unknown at compile time. For example, when executing a task on each value of an input list. Using Dynamic nodes, a new DAG subgraph may be dynamically compiled during runtime and linked to the existing FlyteWorkflow CR. +* **WorkflowHandler**: This handler allows embedding workflows within another workflow definition. The API exposes this functionality using either (1) an inline execution, where the workflow function is invoked directly resulting in a single FlyteWorkflow CR with an appended sub-workflow, or (2) a launch plan, which uses a TODO to create a separate sub-FlyteWorkflow CR whose execution state is linked to the parent FlyteWorkflow CR. +* **BranchHandler**: The branch handler allows the DAG to follow a specific control path based on input (or computed) values. +* **Start / End Handlers**: These are dummy handlers which process input and output data and in turn transition start and end nodes to success. + +FlyteAdmin Events +----------------- + +It should be noted that the WorkflowExecutor, NodeExecutor, and TaskHandlers send events to FlyteAdmin, enabling it to track workflows in near real-time. diff --git a/docs/concepts/component_architecture/native_scheduler_architecture.rst b/docs/concepts/component_architecture/native_scheduler_architecture.rst new file mode 100644 index 0000000000..19f13ef6c7 --- /dev/null +++ b/docs/concepts/component_architecture/native_scheduler_architecture.rst @@ -0,0 +1,77 @@ +.. _native-scheduler-architecture: + +################################### +Flyte Native Scheduler Architecture +################################### + +.. tags:: Advanced, Design + +Introduction +============ +Any workflow engine needs functionality to support scheduled executions. Flyte +fulfills this using an in-built native scheduler, which schedules fixed rate and +cron-based schedules. The workflow author specifies the schedule during the +:ref:`launchplan creation ` +and :ref:`activates or deactivates ` +the schedule using the +:ref:`admin APIs ` +exposed for the launch plan. + +Characteristics +=============== + +#. Cloud provider independent +#. Standard `cron `__ support +#. Independently scalable +#. Small memory footprint +#. Schedules run as lightweight goroutines +#. Fault tolerant and available +#. Support in sandbox environment + + +Components +========== + +Schedule Management +------------------- + +This component supports creation/activation and deactivation of schedules. Each schedule is tied to a launch plan and is versioned in a similar manner. The schedule is created or its state is changed to activated/deactivated whenever the `admin API `__ is invoked for it with `ACTIVE/INACTIVE state `__. This is done either through `flytectl `__ or through any other client that calls the GRPC API. +The API is similar to a launchplan, ensuring that only one schedule is active for a given launchplan. + + +Scheduler +--------- + +This component is a singleton and is responsible for reading the schedules from the DB and running them at the cadence defined by the schedule. The lowest granularity supported is `minutes` for scheduling through both cron and fixed rate schedulers. The scheduler can run in one replica, two at the most during redeployment. Multiple replicas will only duplicate the work, since each execution for a scheduleTime will have a unique identifier derived from the schedule name and the time of the schedule. The idempotency aspect of the admin for the same identifier prevents duplication on the admin side. The scheduler runs continuously in a loop reading the updated schedule entries in the data store and adding or removing the schedules. Removing a schedule will not alter the in-flight goroutines launched by the scheduler. Thus, the behavior of these executions is undefined. + + +Snapshoter +********** + +This component is responsible for writing the snapshot state of all schedules at a regular cadence to a persistent store. It uses a DB to store the GOB format of the snapshot, which is versioned. The snapshot is a map[string]time.Time, which stores a map of schedule names to their last execution times. During bootup, the snapshot is bootstrapped from the data store and loaded into memory. The Scheduler uses this snapshot to schedule any missed schedules. + +CatchupAll-System +***************** +This component runs at bootup and catches up all the schedules to current time, i.e., time.Now(). New runs for the schedules are sent to the admin in parallel. +Any failure in catching up is considered a hard failure and stops the scheduler. The rerun tries to catchup from the last snapshot of data. + +GOCronWrapper +************* + +This component is responsible for locking in the time for the scheduled job to be invoked and adding those to the cron scheduler. It is a wrapper around `this framework `__ for fixed rate and cron schedules that creates in-memory representation of the scheduled job functions. The scheduler schedules a function with scheduleTime parameters. When this scheduled function is invoked, the scheduleTime parameters provide the current schedule time used by the scheduler. This scheduler supports standard cron scheduling which has 5 `fields `__. It requires 5 entries representing ``minute``, ``hour``, ``day of month``, ``month`` and ``day of week``, in that order. + +Job Executor +************ + +The job executor component is responsible for sending the scheduled executions to FlyteAdmin. The job function accepts ``scheduleTime`` and the schedule which is used to create an execution request to the admin. Each job function is tied to the schedule which is executed in a separate goroutine in accordance with the schedule cadence. + +Monitoring +---------- + +To monitor the system health, the following metrics are published by the native scheduler: + +#. JobFuncPanicCounter : count of crashes of the job functions executed by the scheduler. +#. JobScheduledFailedCounter : count of scheduling failures by the scheduler. +#. CatchupErrCounter : count of unsuccessful attempts to catchup on the schedules. +#. FailedExecutionCounter : count of unsuccessful attempts to fire executions of a schedule. +#. SuccessfulExecutionCounter : count of successful attempts to fire executions of a schedule. diff --git a/docs/concepts/console.rst b/docs/concepts/console.rst new file mode 100644 index 0000000000..d872f8990c --- /dev/null +++ b/docs/concepts/console.rst @@ -0,0 +1,128 @@ +.. _divedeep-console: + +############ +FlyteConsole +############ + +.. tags:: Intermediate, Contribute + +FlyteConsole is the web UI for the Flyte platform. Here's a video that dives into the graph UX: + +.. youtube:: 7YSc-QHk_Ec + +********************* +Running FlyteConsole +********************* + +===================== +Install Dependencies +===================== +Running FlyteConsole locally requires `NodeJS `_ and +`yarn `_. Once these are installed, all of the dependencies +can be installed by running ``yarn`` in the project directory. + +====================== +Environment Variables +====================== +Before we can run the server, we need to set up an environment variable or two. + +``ADMIN_API_URL`` (default: `window.location.origin `_) + +FlyteConsole displays information fetched from the FlyteAdmin API. This +environment variable specifies the host prefix used in constructing API requests. + +.. NOTE:: + This is only the host portion of the API endpoint, consisting of the + protocol, domain, and port (if not using the standard 80/443). + +This value will be combined with a suffix (such as ``/api/v1``) to construct the +final URL used in an API request. + +**Default Behavior** + +In most cases, ``FlyteConsole`` is hosted in the same cluster as the Admin +API, meaning that the domain used to access the console is the same as that used to +access the API. For this reason, if no value is set for ``ADMIN_API_URL``, the +default behavior is to use the value of `window.location.origin`. + + +**``BASE_URL`` (default: ``undefined``)** + +This allows running the console at a prefix on the target host. This is +necessary when hosting the API and console on the same domain (with prefixes of +``/api/v1`` and ``/console`` for example). For local development, this is +usually not needed, so the default behavior is to run without a prefix. + + +**``CORS_PROXY_PREFIX`` (default: ``/cors_proxy``)** + +Sets the local endpoint for `CORS request proxying `_. + +=============== +Run the Server +=============== + +To start the local development server, run ``yarn start``. This will spin up a +Webpack development server, compile all of the code into bundles, and start the +NodeJS server on the default port (3000). All requests to the NodeJS server will +be stalled until the bundles have finished. The application will be accessible +at http://localhost:3000 (if using the default port). + +************ +Development +************ + +========== +Storybook +========== + +FlyteConsole uses `Storybook `__. +Component stories live next to the components they test in the ``__stories__`` +directory with the filename pattern ``{Component}.stories.tsx``. + +You can run storybook with ``npm run storybook``, and view the stories at http://localhost:9001. + +============================= +Protobuf and the Network tab +============================= + +Communication with the FlyteAdmin API is done using Protobuf as the +request/response format. Protobuf is a binary format, which means looking at +responses in the Network tab won't be helpful. To make debugging easier, +each network request is logged to the console with its URL, followed by the +decoded Protobuf payload. You must have debug output enabled (on by default in +development) to see these messages. + +============ +Debug Output +============ + +This application makes use of the `debug `_ +library to provide namespaced debug output in the browser console. In +development, all debug output is enabled. For other environments, the debug +output must be enabled manually. You can do this by setting a flag in +localStorage using the console: ``localStorage.debug = 'flyte:*'``. Each module in +the application sets its own namespace. So if you'd like to only view output for +a single module, you can specify that one specifically +(ex. ``localStorage.debug = 'flyte:adminEntity'`` to only see decoded Flyte +Admin API requests). + +.. _cors-proxy: + +============== +CORS Proxying +============== + +In the common hosting arrangement, all API requests are made to the same origin +serving the client application, making CORS unnecessary. For any requests which +do not share the same ``origin`` value, the client application will route +requests through a special endpoint on the NodeJS server. One example would be +hosting the Admin API on a different domain than the console. Another example is fetching execution data from external storage such as S3. This is done to +minimize the extra configuration required for ingress to the Admin API +and data storage, as well as to simplify local development of the console without +the need to grant CORS access to ``localhost``. + +The requests and responses are piped through the NodeJS server with minimal +overhead. However, it is still recommended to host the Admin API and console on +the same domain to prevent unnecessary load on the NodeJS server and extra +latency on API requests due to the additional hop. diff --git a/docs/concepts/control_plane.rst b/docs/concepts/control_plane.rst new file mode 100644 index 0000000000..16656877c0 --- /dev/null +++ b/docs/concepts/control_plane.rst @@ -0,0 +1,14 @@ +.. _control-plane: + +################ +Control Plane +################ + +.. toctree:: + :maxdepth: 1 + + projects + domains + admin + console + dynamic_spec diff --git a/docs/concepts/data_management.rst b/docs/concepts/data_management.rst new file mode 100644 index 0000000000..33a7f499a1 --- /dev/null +++ b/docs/concepts/data_management.rst @@ -0,0 +1,176 @@ +.. _divedeep-data-management: + +################################# +Understand How Flyte Handles Data +################################# + +.. tags:: Basic, Glossary, Design + +Types of Data +============= + +There are two parts to the data in Flyte: + +1. Metadata + +* It consists of data about inputs to a task, and other artifacts. +* It is configured globally for FlytePropeller, FlyteAdmin etc., and the running pods/jobs need access to this bucket to get the data. + +2. Raw data + +* It is the actual data (such as the Pandas DataFrame, Spark DataFrame, etc.). +* Raw data paths are unique for every execution, and the prefixes can be modified per execution. +* None of the Flyte control plane components would access the raw data. This provides great separation of data between the control plane and the data plane. + +.. note: + Metadata and raw data can be present in entirely separate buckets. + + +Let us consider a simple Python task: + +.. code-block:: python + + @task + def my_task(m: int, n: str, o: FlyteFile) -> pd.DataFrame: + ... + +In the above code sample, ``m``, ``n``, ``o`` are inputs to the task. +``m`` of type ``int`` and ``n`` of type ``str`` are simple primitive types, while ``o`` is an arbitrarily sized file. +All of them from Flyte's point of view are ``data``. +The difference lies in how Flyte stores and passes each of these data items. + +For every task that receives input, Flyte sends an **Inputs Metadata** object, which contains all the primitive or simple scalar values inlined, but in the case of +complex, large objects, they are offloaded and the `Metadata` simply stores a reference to the object. In our example, ``m`` and ``n`` are inlined while +``o`` and the output ``pd.DataFrame`` are offloaded to an object store, and their reference is captured in the metadata. + +`Flytekit TypeTransformers` make it possible to use complex objects as if they are available locally - just like persistent filehandles. But Flyte backend only deals with +the references. + +Thus, primitive data types and references to large objects fall under Metadata - `Meta input` or `Meta output`, and the actual large object is known as **Raw data**. +A unique property of this separation is that all `meta values` are read by FlytePropeller engine and available on the FlyteConsole or CLI from the control plane. +`Raw` data is not read by any of the Flyte components and hence it is possible to store it in a completely separate blob storage or alternate stores, which can't be accessed by Flyte control plane components +but can be accessed by users's container/tasks. + +Raw Data Prefix +~~~~~~~~~~~~~~~ + +Every task can read/write its own data files. If ``FlyteFile`` or any natively supported type like ``pandas.DataFrame`` is used, Flyte will automatically offload and download +data from the configured object-store paths. These paths are completely customizable per `LaunchPlan` or `Execution`. + +- The default Rawoutput path (prefix in an object store like S3/GCS) can be configured during registration as shown in :std:ref:`flytectl_register_files`. + The argument ``--outputLocationPrefix`` allows us to set the destination directory for all the raw data produced. Flyte will create randomized folders in this path to store the data. +- To override the ``RawOutput`` path (prefix in an object store like S3/GCS), you can specify an alternate location when invoking a Flyte execution, as shown in the following screenshot of the LaunchForm in FlyteConsole: + + .. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/concepts/data_movement/launch_raw_output.png + +- In the sandbox, the default Rawoutput-prefix is configured to be the root of the local bucket. Hence Flyte will write all the raw data (reference types like blob, file, df/schema/parquet, etc.) under a path defined by the execution. + + +Metadata +~~~~~~~~ + +Metadata in Flyte is critical to enable the passing of data between tasks. It allows to perform in-memory computations for branches or send partial outputs from one task to another or compose outputs from multiple tasks into one input to be sent to a task. + +Thus, metadata is restricted due to its omnipresence. Each `meta output`/`input` cannot be larger than 1MB. If you have `List[int]`, it cannot be larger than 1MB, considering other input entities. In scenarios where large lists or strings need to be sent between tasks, file abstraction is preferred. + +``LiteralType`` & Literals +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +SERIALIZATION TIME +^^^^^^^^^^^^^^^^^^ + +When a task is declared with inputs and outputs, Flyte extracts the interface of the task and converts it to an internal representation called a :std:ref:`ref_flyteidl.core.typedinterface`. +For each variable, a corresponding :std:ref:`ref_flyteidl.core.literaltype` is created. + +For example, the following Python function's interface is transformed as follows: + +.. code-block:: python + + @task + def my_task(a: int, b: str) -> FlyteFile: + """ + Description of my function + + :param a: My input integer + :param b: My input string + :return: My output file + """ + ... + +.. code-block:: + + interface { + inputs { + variables { + key: "a" + value { + type { + simple: INTEGER + } + description: "My input Integer" + } + } + variables { + key: "b" + value { + type { + simple: STRING + } + description: "My input string" + } + } + } + outputs { + variables { + key: "o0" + value { + type { + blob { + } + } + description: "My output File" + } + } + } + } + + +RUNTIME +^^^^^^^ + +At runtime, data passes through Flyte using :std:ref:`ref_flyteidl.core.literal` where the values are set. +For files, the corresponding ``Literal`` is called ``LiteralBlob`` (:std:ref:`ref_flyteidl.core.blob`) which is a binary large object. +Many different objects can be mapped to the underlying `Blob` or `Struct` types. For example, an image is a Blob, a ``pandas.DataFrame`` is a Blob of type parquet, etc. + +Data Movement +============= + +Flyte is primarily a **DataFlow Engine**. It enables movement of data and provides an abstraction to enable movement of data between different languages. + +One implementation of Flyte is the current workflow engine. + +The workflow engine is responsible for moving data from a previous task to the next task. As explained previously, Flyte only deals with Metadata and not the actual Raw data. +The illustration below explains how data flows from engine to the task and how that is transferred between tasks. The medium to transfer the data can change, and will change in the future. +We could use fast metadata stores to speed up data movement or exploit locality. + +Between Flytepropeller and Tasks +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/concepts/data_movement/flyte_data_movement.png + + +Between Tasks +~~~~~~~~~~~~~~ + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/concepts/data_movement/flyte_data_transfer.png + + +Bringing in Your Own Datastores for Raw Data +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Flytekit has a pluggable `data persistence layer `__. +This is driven by PROTOCOL. +For example, it is theoretically possible to use S3 ``s3://`` for metadata and GCS ``gcs://`` for raw data. It is also possible to create your own protocol ``my_fs://``, to change how data is stored and accessed. +But for Metadata, the data should be accessible to Flyte control plane. + +Data persistence is also pluggable. By default, it supports all major blob stores and uses an interface defined in Flytestdlib. diff --git a/docs/concepts/domains.rst b/docs/concepts/domains.rst new file mode 100644 index 0000000000..bb306924dd --- /dev/null +++ b/docs/concepts/domains.rst @@ -0,0 +1,13 @@ +.. _divedeep-domains: + +Domains +======= + +.. tags:: Basic, Glossary + +Domains provide an abstraction to isolate resources and feature configuration for different +deployment environments. + +For example: We develop and deploy Flyte workflows in development, staging, and production. We configure Flyte domains with those names, and specify lower resource limits on the development and staging domains than production domains. + +We also use domains to disable launch plans and schedules from development and staging domains, since those features are typically meant for production deployments. \ No newline at end of file diff --git a/docs/concepts/dynamic_spec.rst b/docs/concepts/dynamic_spec.rst new file mode 100644 index 0000000000..4e9e11ad3c --- /dev/null +++ b/docs/concepts/dynamic_spec.rst @@ -0,0 +1,50 @@ +.. _divedeep-dynamic-spec: + +Dynamic Job Spec +================ + +.. tags:: Basic, Design + +A dynamic job spec is a subset of the entire workflow spec that defines a set of tasks, workflows, nodes, and output bindings that control how the job should assemble its outputs. + +This spec is currently only supported as an intermediate step in running Dynamic Tasks. + +.. code-block:: protobuf + :caption: Dynamic job spec in Protobuf + + message DynamicJobSpec { + repeated Node nodes = 1; + int64 min_successes = 2; + repeated Binding outputs = 3; + + repeated TaskTemplate tasks = 4; + repeated WorkflowTemplate subworkflows = 5; + } + +.. _divedeep-dynamic-tasks: + +Tasks +----- + +Defines one or more :ref:`Tasks ` that can then be referenced in the spec. + +.. _divedeep-dynamic-subworkflows: + +Subworkflows +------------ + +Defines zero or more :ref:`Workflows ` that can then be referenced in the spec. + +.. _divedeep-dynamic-nodes: + +Nodes +----- + +Defines one or more :ref:`Nodes ` that can run in parallel to produce the final outputs of the spec. + +.. _divedeep-dynamic-outputs: + +Outputs +------- + +Defines one or more binding that instructs engine on how to assemble the final outputs. \ No newline at end of file diff --git a/docs/concepts/execution_timeline.rst b/docs/concepts/execution_timeline.rst new file mode 100644 index 0000000000..276930c94e --- /dev/null +++ b/docs/concepts/execution_timeline.rst @@ -0,0 +1,72 @@ +.. _divedeep-execution-timeline: + +######################################## +Timeline of a workflow execution +######################################## + +.. tags:: Intermediate, Glossary + +The illustration below shows the timeline view of a workflow execution. + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/deployment/monitoring/flyte_wf_timeline.svg?sanitize=true + + +The illustration above refers to a simple workflow, with 2 nodes N1 & N2. This can be represented as follows, + +.. mermaid:: + + graph LR; + Start --> N1; + N1 --> N2; + N2 --> End; + + +Acceptance Latency +==================== +Every workflow starts in the ``Acceptance`` phase. Acceptance refers to the time between FlyteAdmin receiving an execution request and FlytePropeller evaluating the first round of workflow. +Usually, within this phase, the K8s queuing latency is the largest contributor to latency where the overall acceptance latency of <5s is desirable. + +Transition Latency +=================== +Transition latency refers to the time between successive node executions, that is, between ``N1`` and ``N2``. For the first node ``N1``, this latency also encapsulates executing the start node. + +Similarly, the last node also encapsulates executing end node. ``Start Node`` and ``End Node`` are capstones inserted to mark the beginning and end of the DAG. + +The latency involves time consumed to: + +#. Gather outputs for a node after the node completes execution. +#. Send an observation event to FlyteAdmin. Failing to do so will be regarded as an error and will be tried until it succeeds or system max retries are exhausted (the number of max system retries is configured to be 30 by default and can be altered per deployment). +#. Persist data to Kubernetes. +#. Receive the persisted object back from Kubernetes (as this process is eventually consistent using informer caches). +#. Gather inputs for a node before the node starts. +#. Send a queued event for the next node to FlyteAdmin (this is what is persisted and drives the UI/CLI and historical information). + +Queuing Latency +================ +Queuing latency is the time taken by Kubernetes to start the pod, other services to start the job, HTTP throttle to be met, or any rate-limiting that needs to be overcome. This +is usually tied to the available resources and quota, and is out of control for Flyte. + +Completion Latency +=================== +Completion latency is the time taken to mark the workflow as complete and accumulate outputs of a workflow after the last node completes its execution. + + +Overview of Various Latencies in FlytePropeller +================================================= + +=================================== ================================================================================================================================== + Description of main events for workflow execution +----------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Events Description +=================================== ================================================================================================================================== +Acceptance Measures the time between when we receive service call to create an Execution (Unknown) and when it has moved to Queued. +Transition Latency Measures the latency between two consecutive node executions, the time spent in Flyte engine. +Queuing Latency Measures the latency between the time a node's been queued to the time the handler reported the executable moved to running state. +Task Execution Actual time spent executing user code +Repeat steps 2-4 for every task +Transition Latency See #2 +Completion Latency Measures the time between when the WF moved to succeeding/failing state and when it finally moved to a terminal state. +=================================== ================================================================================================================================== + +.. note:: + **The core team is working on optimizing Completion Latency, Transition Latency, and Acceptance Latency.** \ No newline at end of file diff --git a/docs/concepts/executions.rst b/docs/concepts/executions.rst new file mode 100644 index 0000000000..b6ee602520 --- /dev/null +++ b/docs/concepts/executions.rst @@ -0,0 +1,20 @@ +.. _divedeep-executions: + +########## +Executions +########## + +.. tags:: Basic, Glossary + +**Executions** are instances of workflows, nodes or tasks created in the system as a result of a user-requested execution or a scheduled execution. + +Typical Flow Using Flytectl +--------------------------- + +* When an execution of a workflow is triggered using UI/Flytecli/other stateless systems, the system first calls the ``getLaunchPlan`` endpoint and retrieves a launch plan matching the given version. The launch plan definition includes definitions of all input variables declared for the workflow. +* The user-side component then ensures that all the required inputs are supplied and requests the FlyteAdmin service for an execution. +* The FlyteAdmin service validates the inputs, ensuring that they are all specified and, if required, within the declared bounds. +* FlyteAdmin then fetches the previously validated and compiled workflow closure and translates it to an executable format with all the inputs. +* This executable workflow is launched on Kubernetes with an execution record in the database. + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/concepts/executions/flyte_wf_execution_overview.svg?sanitize=true \ No newline at end of file diff --git a/docs/concepts/flyte_console.rst b/docs/concepts/flyte_console.rst new file mode 100644 index 0000000000..8e9484789b --- /dev/null +++ b/docs/concepts/flyte_console.rst @@ -0,0 +1,232 @@ +.. _ui: + +How to Use Flyte UI +=================== + +.. tags:: Basic, UI + +Flyte UI is a web-based user interface for Flyte. It helps interact with Flyte objects and builds DAGs out of your workflows. + +With Flyte UI, you can: + +* Launch tasks +* Launch workflows +* View Versioned Tasks and Workflows +* Trigger Versioned Tasks and Workflows +* Inspect Executions through Inputs, Outputs, Logs, and Graphs +* Clone Executions +* Relaunch Executions +* Recover Executions + +.. note:: + `FlyteConsole `__ hosts the Flyte user interface code. + +Launching Workflows +------------------- + +You can launch a workflow by clicking on the **Launch Workflow** button. Workflows are viewable after they are registered. +The UI should be accessible at http://localhost:30081/console. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/launch_execution_001.png + :alt: "Launch Workflow" button + + Launch a workflow using the "Launch Workflow" button. + +| + +The end-to-end process from writing code to registering workflows is present in the :std:ref:`getting-started`. + +A pop-up window appears with input fields that the execution requires upon clicking the **Launch Workflow** button. +If the default inputs are given, they will be auto-populated. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/launch_execution_002.png + :alt: Launch form + + A pop-up window appears after clicking the "Launch Workflow" button. + +| + +An execution can be terminated/aborted by clicking on the **Terminate** button. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/launch_execution_003.png + :alt: "Terminate" button + + Terminate an execution by clicking the "Terminate" button. + +| + +Launching Tasks +--------------- + +You can launch a task by clicking on the **Launch Task** button. Tasks are viewable after they are registered. +The UI should be accessible at http://localhost:30081/console. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/launch_task_001.png + :alt: "Launch Task" button + + Launch a task by clicking the "Launch Task" button. + +| + +A pop-up window appears with input fields that the task requires and the role with which the task has to run on clicking the **Launch Task** button. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/launch_task_002.png + :alt: Launch form + + A pop-up window appears on clicking the "Launch Task" button. + +| + +Viewing Versioned Tasks and Workflows +------------------------------------- + +Every registered Flyte entity is tagged with a version. All the registered versions of workflows and tasks are viewable in the UI. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/versioned_executions.png + :alt: Versioned workflows + + View versioned workflows. + +| + +Triggering Versioned Tasks and Workflows +---------------------------------------- + +Every registered Flyte entity is versioned and can be triggered anytime. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/trigger_versioned_executions.png + :alt: Trigger versioned workflows + + Trigger versioned workflows. + +| + +Inspecting Executions +--------------------- + +Executions can be inspected through the UI. Inputs and Outputs for every node and execution can be viewed. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/inspect_execution_001.png + :alt: Node's inputs and outputs + + View every execution node's inputs and outputs. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/inspect_execution_002.png + :alt: Execution's inputs and outputs + + View every execution's inputs and outputs. + +| + +Logs are accessible as well. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/inspect_execution_003.png + :alt: Logs + + View Kubernetes logs. + +| + +Every execution has two views: Nodes and Graph. + +A node in the nodes view encapsulates an instance of a task, but it can also contain an entire subworkflow or trigger an external workflow. +More about nodes can be found in :std:ref:`divedeep-nodes`. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/inspect_execution_004.png + :alt: Nodes + + Inspect execution's nodes in the UI. + +| + +Graph view showcases a static DAG. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/inspect_execution_005.png + :alt: DAG + + Inspect execution's DAG in the UI. + +| + +Cloning Executions +------------------ + +An execution in the ``RUNNING`` state can be cloned. + +Click on the ellipsis on the top right corner of the UI. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/clone_execution_001.png + :alt: Clone execution + + Step 1: Click on the ellipsis. + +| + +Click on the **Clone Execution** button. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/clone_execution_002.png + :alt: Clone execution + + Step 2: "Clone execution" button. + +| + +Relaunching Executions +---------------------- + +The **Relaunch** button allows you to relaunch a terminated execution with pre-populated inputs. +This option can be helpful to try out a new version of a Flyte entity. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/relaunch_execution.png + :alt: Relaunch an execution + + Relaunch an execution. + +| + +A pop-up window appears on clicking the relaunch button, allowing you to modify the version and inputs. + +Recovering Executions +--------------------- + +Recovery mode allows you to recover an individual execution by copying all successful node executions and running from the failed nodes. +The **Recover** button helps recover a failed execution. + +| + +.. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/flyteconsole/recover_execution.png + :alt: Recover an execution + + Recover an execution. + +| diff --git a/docs/concepts/flyte_wf_tasks_high_level.png b/docs/concepts/flyte_wf_tasks_high_level.png new file mode 100644 index 0000000000000000000000000000000000000000..83e987ee18ed79387f944d963e8d40f0bedf1725 GIT binary patch literal 43187 zcmeFZXIPWX`sjsIlsa~u)wbSxJzF=x4P9qlx7@}&S;4wj zrf55AH#BOMXRYvvbd)yY0wphPKcDblQQt@|^+fcXoCQAk=v2dT?bepJ7^7H{5Z0&f zsE_1c)8-L;69?My|Ns0u2?QePg6l3m&|zQmI`m;c!ky8HLoR4`LDBBzT8B7#_`;rn zVApbeDtuMCc2-vjx!2cuC[F0eoP4AD%tW147Ue2z;S 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 DKQ~+C literal 0 HcmV?d00001 diff --git a/docs/concepts/launchplans.rst b/docs/concepts/launchplans.rst new file mode 100644 index 0000000000..2efb6af998 --- /dev/null +++ b/docs/concepts/launchplans.rst @@ -0,0 +1,57 @@ +.. _divedeep-launchplans: + +Launch plans +============ + +.. tags:: Basic, Glossary, Design + +Launch plans help execute workflows. A workflow can be associated with multiple launch plans and launch plan versions, but an individual launch plan is always associated with a single, specific workflow. After creating a launch plan, it is easy to share and execute them. + +Launch plans provide a way to templatize Flyte workflow invocations. Launch plans contain a set of bound workflow inputs that are passed as arguments to create an execution. Launch plans do not necessarily contain the entire set of required workflow inputs, but a launch plan is always necessary to trigger an execution. Additional input arguments can be provided at execution time to supplement launch plan static input values. + +In addition to templatized inputs, launch plans allow you to run your workflow on one or multiple schedules. Each launch +plan can optionally define a single schedule (which can be easily disabled by disabling the launch plan) as well as +optional notifications. Refer to the :ref:`deployment-configuration-notifications` for a deep dive into available notifications. + +The Association between Workflows and LaunchPlans +------------------------------------------------- + +Every workflow comes with a `default` launch plan that has the same name as that of a workflow. The default launch plan is authored (in code) as part of creating a new workflow. +A launch plan version can only ever be mapped to one workflow version; meaning a launch plan version cannot be used twice. This is because part of what makes a new launch plan version is the mapping to the specific workflow version. + +.. note:: + Users rarely interact with the default launch plan. + +Suppose we have ``Workflow A`` in ``version 1``, ``LaunchPlans`` ``A`` and ``B`` in ``version 1``, and ``LaunchPlan`` ``B`` in ``version 2``, then: + +1. ``Workflow A`` can be associated with ``LaunchPlan A`` (version 1); +2. ``Workflow A`` can be associated with ``LaunchPlan B`` (different launch plan name; version 1); +3. ``Workflow A`` can be associated with ``LaunchPlan B`` (version 2). + + +What do Launch Plans Provide? +------------------------------ + +- One click invocation of workflows with predefined inputs and friendly launch plan names. +- Multiple schedules with different default values for inputs per workflow. +- Ability to easily enable and disable schedules. +- Can be created dynamically with flyteclient or statically using the Flyte SDK. +- Associate different notifications with your workflows. +- Restrict inputs to be passed to the workflows at launch time using the :ref:`fixed_inputs ` parameter. +- Multiple versions of the launch plan (with same name) with only one active version. Schedule will reflect only on the active launch plan version. + +.. _concepts-launchplans-inputs: + +Launch plan inputs +------------------ +Generally launch plan inputs correspond to their related workflow definition's inputs, in that the variable type and names are expected to match. Launch plans cannot introduce any inputs not defined in the core workflow definition. However, launch plan inputs differ slightly from workflow inputs in that the former are categorized into **default inputs** and **fixed inputs**. + +Default Inputs +^^^^^^^^^^^^^^ +Default inputs behave much like default workflow inputs. As their name implies, default inputs provide default workflow input values at execution time in the absence of any dynamically provided values. + +.. _fixed_inputs: + +Fixed Inputs +^^^^^^^^^^^^ +Fixed inputs cannot be overridden. If a workflow is executed with a launch plan and dynamic inputs that attempt to redefine the launch plan's fixed inputs, the execution creation request *will fail*. diff --git a/docs/concepts/nodes.rst b/docs/concepts/nodes.rst new file mode 100644 index 0000000000..d67c15457c --- /dev/null +++ b/docs/concepts/nodes.rst @@ -0,0 +1,34 @@ +.. _divedeep-nodes: + +Nodes +===== + +.. tags:: Basic, Glossary + +A node represents a unit of execution or work within a workflow. Ordinarily, a node encapsulates an instance of +a :ref:`task `, but it can also contain an entire subworkflow or trigger an external workflow. +Nodes can have inputs and outputs, which are used to coordinate task inputs and outputs. +Moreover, node outputs can be used as inputs to other nodes within a workflow. + +Tasks are always encapsulated within a node. Like tasks, nodes can come in a variety of flavors determined by their *target*. +These targets include :ref:`task nodes `, :ref:`workflow nodes `, and :ref:`branch nodes `. + +.. _divedeep-task-nodes: + +Task Nodes +---------- + +Tasks referenced in a workflow are always enclosed in nodes. This extends to all task types. +For example, an array task will be enclosed by a single node. + +.. _divedeep-workflow-nodes: + +Workflow Nodes +-------------- +A node can contain an entire sub-workflow. Since workflow executions always require a launch plan, workflow nodes have a reference to a launch plan to trigger their enclosed workflows. + +.. _divedeep-branch-nodes: + +Branch Nodes +------------ +Branch nodes alter the flow of the workflow graph. Conditions at runtime are evaluated to determine the control flow. diff --git a/docs/concepts/projects.rst b/docs/concepts/projects.rst new file mode 100644 index 0000000000..99ed0daf3f --- /dev/null +++ b/docs/concepts/projects.rst @@ -0,0 +1,14 @@ +.. _divedeep-projects: + +Projects +======== + +.. tags:: Basic, Glossary + +A project in Flyte is a group of :ref:`workflows ` and :ref:`tasks ` tied together to achieve a goal. + +A Flyte project can map to an engineering project or everything that's owned by a team or an individual. There cannot be multiple projects with the same name in Flyte. + +Since the fully-qualified name for tasks and workflows include the project and domain name, the task/workflow names are only required to be unique within a project. The workflows in a project ``A`` can refer to tasks and workflows in other projects using the fully-qualified name. + +Flyte allows users to set resource limits and provides basic reports and dashboards automatically for each project. The information captured in these reports includes workflow/task level insights, resource usage, and billing information. \ No newline at end of file diff --git a/docs/concepts/registration.rst b/docs/concepts/registration.rst new file mode 100644 index 0000000000..bc745f7a0f --- /dev/null +++ b/docs/concepts/registration.rst @@ -0,0 +1,33 @@ +.. _divedeep-registration: + +############ +Registration +############ + +.. tags:: Basic, Glossary, Design + +During registration, Flyte validates the workflow structure and saves the workflow. The registration process also updates the workflow graph. + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/concepts/executions/flyte_wf_registration_overview.svg?sanitize=true + +Typical Flow +------------- +The following steps elaborate on the specifics of the registration process: + +* Define the tasks using the :py:mod:`Flytekit ` Task Definition language. +* Define a workflow using the :py:mod:`Flytekit ` Workflow definition language. +* Use `flytectl register CLI `__ to compile the tasks into their serialized representation as described in :std:ref:`Flyte Specification language `. During this, the task representation is bound to a container that constitutes the code for the task. This associated entity is registered with FlyteAdmin using the registerTask API. +* Use flytectl register CLI to compile the workflow into their serialized representation as described in :std:ref:`Flyte Specification language `. The referenced tasks are replaced by their FlyteAdmin registered Identifiers, obtained in the previous step. The associated entity is registered with FlyteAdmin using the registerWorkflow API. +* Launch an execution using the FlyteAdmin launch execution API, which requires the necessary inputs provided. This is automatically done if the user uses flytectl to launch the execution. +* Use the FlyteAdmin read APIs to get details of the execution, monitor it to completion, or retrieve a historical execution. +* **OR** use the FlyteConsole to visualize the execution in real time as it progresses or visualize any historical execution. The console makes it easy to view debugging information for the execution. +* Set specific rules such as *notification* on **failure** or **success** or publish all events in the execution to a pub-sub system. +* Query the datastore to get a summary of all the executions and the compute resources consumed. + +.. note:: + Workflows and tasks are purely specifications and can be provided using tools like ``YAML``, ``JSON``, ``protobuf binary`` or any other programming language, and hence registration is possible using other tools. Contributions welcome! + +Registration in the Backend +--------------------------- + +When FlyteAdmin receives a workflow registration request, it uses the workflow compiler to compile and validate the workflow. It also fetches all the referenced tasks and creates a complete workflow closure, which is stored in the metastore. If the workflow compilation fails, the compiler returns an error to the client. diff --git a/docs/concepts/schedules.rst b/docs/concepts/schedules.rst new file mode 100644 index 0000000000..34644b217b --- /dev/null +++ b/docs/concepts/schedules.rst @@ -0,0 +1,102 @@ +.. _concepts-schedules: + +Schedules +========= + +.. tags:: Basic, Glossary + +Workflows can be run automatically using :ref:`schedules ` associated with launch plans. + +Only one launch plan version for a given {Project, Domain, Name} combination can be active, which means only one schedule can be active for a launch plan. This is because a single active schedule can exist across all versions of the launch plan. + +A :ref:`workflow ` version can have multiple schedules associated with it, given that these schedules exist as versions of different launch plans. + +Creating a new schedule creates a new version of the launch plan. +If you wish to change a schedule, you will have to create a new version of that launch plan since a **schedule cannot be edited**. + +FlyteAdmin keeps track of the newly-added schedules, and searches through all the versions of launch plans to set them to 'deactivated'. + +The launch plan versions with schedules that were previously deactivated can be manually used, by clicking on the launch button and selecting the specific launch plan version. + +Let's now look at how schedules can be defined through cron_expression_ or rate_unit_. + +.. _cron_expression: + +Cron Expression +--------------- +Cron expression strings use :ref:`this ` syntax. They are validated at launch plan registration time. + +.. _rate_unit: + +Format +------ + +A cron expression represents a set of times, with the help of 5 space-separated fields. + +.. _cron_expression_table: + ++--------------+------------+-----------------+----------------------------+ +| Field name | Mandatory? | Allowed values | Allowed special characters | ++==============+============+=================+============================+ +| Minutes | Yes | 0-59 | * / , - | ++--------------+------------+-----------------+----------------------------+ +| Hours | Yes | 0-23 | * / , - | ++--------------+------------+-----------------+----------------------------+ +| Day of month | Yes | 1-31 | * / , - ? | ++--------------+------------+-----------------+----------------------------+ +| Month | Yes | 1-12 or JAN-DEC | * / , - | ++--------------+------------+-----------------+----------------------------+ +| Day of week | Yes | 0-6 or SUN-SAT | * / , - ? | ++--------------+------------+-----------------+----------------------------+ + +**Note**: The 'Month' and 'Day of week' fields are case insensitive. + + +Cron schedules +-------------- +An incorrect cron schedule expression leads to a failure in triggering the schedule. :ref:`Here ` is a table that shows the format of a cron expression. + +Below is another example: + +.. code-block:: default + + cron_lp_every_min_of_hour = LaunchPlan.get_or_create( + name="my_cron_scheduled_lp", + workflow=date_formatter_wf, + schedule=CronSchedule( + # Note that kickoff_time_input_arg matches the workflow input we defined above: kickoff_time + # But in case you are using the AWS scheme of schedules and not using the native scheduler then switch over the schedule parameter with cron_expression + schedule="@hourly", # Following schedule runs every hour at beginning of the hour + kickoff_time_input_arg="kickoff_time", + ), + + ) + + +Fixed rate schedules +---------------------- +Instead of cron schedules, fixed rate schedules can be used. + +You can specify the duration in the schedule using `timedelta`, that supports `minutes`, `hours`, `days` and `weeks`. + +:ref:`Here ` is an example with duration in `minutes`. + +Below is an example with duration in `days`. + +.. code-block:: default + + fixed_rate_lp_days = LaunchPlan.get_or_create( + name="my_fixed_rate_lp_days", + workflow=positive_wf, + # Note that the above workflow doesn't accept any kickoff time arguments. + # We omit the ``kickoff_time_input_arg`` from the FixedRate schedule invocation + schedule=FixedRate(duration=timedelta(days=1)), + fixed_inputs={"name": "you"}, + +) + + +Rate Unit +--------- + +Schedules can also be defined using fixed rates in units of **days**, **hours** and **minutes**. diff --git a/docs/concepts/state_machine.rst b/docs/concepts/state_machine.rst new file mode 100644 index 0000000000..8507a59d9c --- /dev/null +++ b/docs/concepts/state_machine.rst @@ -0,0 +1,154 @@ +.. _divedeep-state-machine: + +################################################ +Understanding the State Transition in a Workflow +################################################ + +.. tags:: Basic, Design + +High Level Overview of How a Workflow Progresses to Success +=========================================================== + +.. mermaid:: + + flowchart TD + id1(( )) + id1 --> Ready + Ready --> Running + subgraph Running + id2(( )) + id2 --> NodeQueued + NodeQueued --> NodeRunning + subgraph NodeRunning + id3(( )) + id3 --> TaskQueued + TaskQueued --> TaskRunning + TaskRunning --> TaskSuccess + end + TaskSuccess --> NodeSuccess + end + NodeSuccess --> Success + + +This state diagram illustrates a high-level, simplistic view of the state transitions that a workflow with a single task and node would go through as the user observes success. + +The following sections explain the various observable (and some hidden) states for workflow, node, and task state transitions. + +Workflow States +=============== + +.. mermaid:: + + flowchart TD + Queued -->|On system errors more than threshold| Aborted + Queued --> Ready + Ready--> |Write inputs to workflow| Running + Running--> |On system error| Running + Running--> |On all Nodes Success| Succeeding + Succeeding--> |On successful event send to Admin| Succeeded + Succeeding--> |On system error| Succeeding + Ready--> |On precondition failure| Failing + Running--> |On any Node Failure| Failing + Ready--> |On user initiated abort| Aborting + Running--> |On user initiated abort| Aborting + Succeeding--> |On user initiated abort| Aborting + Failing--> |If Failure node exists| HandleFailureNode + Failing--> |On user initiated abort| Aborting + HandleFailureNode--> |On completing failure node| Failed + HandleFailureNode--> |On user initiated abort| Aborting + Failing--> |On successful send of Failure node| Failed + Aborting--> |On successful event send to Admin| Aborted + +A workflow always starts in the ``Ready`` state and ends either in ``Failed``, ``Succeeded``, or ``Aborted`` state. +Any system error within a state causes a retry on that state. These retries are capped by :ref:`system retries ` which eventually lead to an ``Aborted`` state if the failure persists. + +Every transition between states is recorded in FlyteAdmin using :std:ref:`workflowexecutionevent `. + +The phases in the above state diagram are captured in the admin database as specified here :std:ref:`workflowexecution.phase ` and are sent as a part of the Execution event. + +The state machine specification for the illustration can be found `here `__. + + +Node States +=========== + +.. mermaid:: + + flowchart TD + id1(( )) + id1-->NotYetStarted + id1-->|Will stop the node execution |Aborted + NotYetStarted-->|If all upstream nodes are ready, i.e, inputs are ready | Queued + NotYetStarted--> |If the branch was not taken |Skipped + Queued-->|Start task execution- attempt 0 | Running + Running-->|If task timeout has elapsed and retry_attempts >= max_retries|TimingOut + Running-->|Internal state|Succeeding + Running-->|For dynamic nodes generating workflows| DynamicRunning + DynamicRunning-->TimingOut + DynamicRunning-->RetryableFailure + TimingOut-->|If total node timeout has elapsed|TimedOut + DynamicRunning-->Succeeding + Succeeding-->|User observes the task as succeeded| Succeeded + Running-->|on retryable failure| RetryableFailure + RetryableFailure-->|if retry_attempts < max_retries|Running + RetryableFailure-->|retry_attempts >= max_retries|Failing + Failing-->Failed + Succeeded-->id2(( )) + Failed-->id2(( )) + + +This state diagram illustrates the node transition through various states. This is the core finite state machine for a node. +From the user's perspective, a workflow simply consists of a sequence of tasks. But to Flyte, a workflow internally creates a meta entity known as **node**. + +Once a Workflow enters the ``Running`` state, it triggers the phantom ``start node`` of the workflow. The ``start node`` is considered to be the entry node of any workflow. +The ``start node`` begins by executing all its child-nodes using a modified Depth First Search algorithm recursively. + +Nodes can be of different types as listed below, but all the nodes traverse through the same transitions: + +#. Start Node - Only exists during the execution and is not modeled in the core spec. +#. :std:ref:`Task Node ` +#. :std:ref:`Branch Node ` +#. :std:ref:`Workflow Node ` +#. Dynamic Node - Just a task node that does not return output but constitutes a dynamic workflow. + When the task runs, it remains in the ``RUNNING`` state. Once the task completes and Flyte starts executing the dynamic workflow, + the overarching node that contains both the original task and the dynamic workflow enters `DYNAMIC_RUNNING` state. +#. End Node - Only exists during the execution and is not modeled in the core spec + +Every transition between states is recorded in FlyteAdmin using :std:ref:`nodeexecutionevent `. + +Every ``NodeExecutionEvent`` can have any :std:ref:`nodeexecution.phase `. + +.. note:: TODO: Add explanation for each phase. + +The state machine specification for the illustration can be found `here `__. + +Task States +=========== + +.. mermaid:: + + flowchart TD + id1(( )) + id1-->|Aborted by NodeHandler- timeouts, external abort, etc,.| NotReady + id1-->Aborted + NotReady-->|Optional-Blocked on resource quota or resource pool | WaitingForResources + WaitingForResources--> |Optional- Has been submitted, but hasn't started |Queued + Queued-->|Optional- Prestart initialization | Initializing + Initializing-->|Actual execution of user code has started|Running + Running-->|Successful execution|Success + Running-->|Failed with a retryable error|RetryableFailure + Running-->|Unrecoverable failure, will stop all execution|PermanentFailure + Success-->id2(( )) + RetryableFailure-->id2(( )) + PermanentFailure-->id2(( )) + + +The state diagram above illustrates the various states through which a task transitions. This is the core finite state machine for a task. + +Every transition between states is recorded in FlyteAdmin using :std:ref:`taskexecutionevent `. + +Every ``TaskExecutionEvent`` can have any :std:ref:`taskexecution.phase `. + +.. note:: TODO: Add explanation for each phase. + +The state machine specification for the illustration can be found `here `__. diff --git a/docs/concepts/tasks.rst b/docs/concepts/tasks.rst new file mode 100644 index 0000000000..301287fc7b --- /dev/null +++ b/docs/concepts/tasks.rst @@ -0,0 +1,123 @@ +.. _divedeep-tasks: + +Tasks +===== + +.. tags:: Basic, Glossary + +Tasks are fully independent units of execution and first-class entities of Flyte. +They are the fundamental building blocks and extension points that encapsulate the users' code. + +Characteristics +--------------- + +A Flyte task is characterized by: + +1. A combination of :ref:`projects ` and :ref:`domains `, +2. A unique unicode name (we recommend it not to exceed 32 characters), +3. A version string, and/or +4. *Optional* Task interface definition. + + For tasks to exchange data with each other, a task can define a signature (much like a function/method + signature in programming languages). A task interface defines the input and output variables — + :std:ref:`variablesentry ` + and their types, :std:ref:`literaltype `. + +Can "X" Be a Flyte Task? +------------------------- + +When deciding if a unit of execution constitutes a Flyte task, consider these questions: + +- Is there a well-defined graceful/successful exit criteria for the task? A task is expected to exit after completion of input processing. +- Is it repeatable? Under certain circumstances, a task might be retried, rerun, etc. with the same inputs. It is expected + to produce the same output every single time. For example, avoid using random number generators with current clock as seed. Use a system-provided clock as the seed instead. +- Is it a pure function, i.e., does it have side effects that are unknown to the system (calls a web-service)? It is recommended to avoid side-effects in tasks. When side-effects are evident, ensure that the operations are idempotent. + +Dynamic Tasks +-------------- + +"Dynamic tasks" is a misnomer. +Flyte is one-of-a-kind workflow engine that ships with the concept of truly `Dynamic Workflows `__! +Users can generate workflows in reaction to user inputs or computed values at runtime. +These executions are evaluated to generate a static graph before execution. + +Extending Task +--------------- + +Plugins +^^^^^^^ + +Flyte exposes an extensible model to express tasks in an execution-independent language. +It contains first-class task plugins (for example: `Papermill `__, +`Great Expectations `__, and :ref:`more `.) +that execute the Flyte tasks. +Almost any action can be implemented and introduced into Flyte as a "Plugin", which includes: + +- Tasks that run queries on distributed data warehouses like Redshift, Hive, Snowflake, etc. +- Tasks that run executions on compute engines like Spark, Flink, AWS Sagemaker, AWS Batch, Kubernetes pods, jobs, etc. +- Tasks that call web services. + +Flyte ships with certain defaults, for example, running a simple Python function does not need any hosted service. Flyte knows how to +execute these kinds of tasks on Kubernetes. It turns out these are the vast majority of tasks in machine learning, and Flyte is adept at +handling an enormous scale on Kubernetes. This is achieved by implementing a unique scheduler on Kubernetes. + +Types +^^^^^ + +It is impossible to define the unit of execution of a task in the same way for all tasks. Hence, Flyte allows for different task +types in the system. Flyte has a set of defined, battle-tested task types. It allows for a flexible model to +:std:ref:`define new types `. + +Inherent Features +----------------- + +Fault tolerance +^^^^^^^^^^^^^^^ + +In any distributed system, failure is inevitable. Allowing users to design a fault-tolerant system (e.g. workflow) is an inherent goal of Flyte. +At a high level, tasks offer two parameters to achieve fault tolerance: + +**Retries** + +Tasks can define a retry strategy to let the system know how to handle failures (For example: retry 3 times on any kind of error). + +There are two kinds of retries: + +1. System retry: It is a system-defined, recoverable failure that is used when system failures occur. The number of retries is validated against the number of system retries. + +.. _system-retry: + +System retry can be of two types: + +- **Downstream System Retry**: When a downstream system (or service) fails, or remote service is not contactable, the failure is retried against the number of retries set `here `__. This performs end-to-end system retry against the node whenever the task fails with a system error. This is useful when the downstream service throws a 500 error, abrupt network failure, etc. + +- **Transient Failure Retry**: This retry mechanism offers resiliency against transient failures, which are opaque to the user. It is tracked across the entire duration of execution. It helps Flyte entities and the additional services connected to Flyte like S3, to continue operating despite a system failure. Indeed, all transient failures are handled gracefully by Flyte! Moreover, in case of a transient failure retry, Flyte does not necessarily retry the entire task. “Retrying an entire task” means that the entire pod associated with the Flyte task would be rerun with a clean slate; instead, it just retries the atomic operation. For example, Flyte tries to persist the state until it can, exhausts the max retries, and backs off. + + To set a transient failure retry: + + - Update `MaxWorkflowRetries `__ in the propeller configuration. + + - Or update `max-workflow-retries `__ in helm. + +2. User retry: If a task fails to execute, it is retried for a specific number of times, and this number is set by the user in `TaskMetadata `__. The number of retries must be less than or equal to 10. + +.. note:: + + Recoverable vs. Non-Recoverable failures: Recoverable failures will be retried and counted against the task's retry count. Non-recoverable failures will just fail, i.e., the task isn’t retried irrespective of user/system retry configurations. All user exceptions are considered non-recoverable unless the exception is a subclass of FlyteRecoverableException. + + +.. note:: + + `RFC 3902 `_ implements an alternative, simplified retry behaviour with which both system and user retries are counted towards a single retry budget defined in the task decorator (thus, without a second retry budget defined in the platform configuration). The last retries are always performed on non-spot instances to guarantee completion. To activate this behaviour, set ``configmap.core.propeller.node-config.ignore-retry-cause`` to ``true`` in the helm values. + + +**Timeouts** + +To ensure that the system is always making progress, tasks must be guaranteed to end gracefully/successfully. The system defines a default timeout period for the tasks. It is possible for task authors to define a timeout period, after which the task is marked as ``failure``. Note that a timed-out task will be retried if it has a retry strategy defined. The timeout can be handled in the `TaskMetadata `__. + + +Caching/Memoization +^^^^^^^^^^^^^^^^^^^ + +Flyte supports memoization of task outputs to ensure that identical invocations of a task are not executed repeatedly, thereby saving compute resources and execution time. For example, if you wish to run the same piece of code multiple times, you can reuse the output instead of re-computing it. +For more information on memoization, refer to the :std:doc:`Caching Example `. diff --git a/docs/concepts/versioning.rst b/docs/concepts/versioning.rst new file mode 100644 index 0000000000..42df830e6c --- /dev/null +++ b/docs/concepts/versioning.rst @@ -0,0 +1,104 @@ +.. _divedeep-versioning: + +Versions +======== + +.. tags:: Basic, Glossary + +One of the most important features and reasons for certain design decisions in Flyte is the need for machine learning and data practitioners to experiment. +When users experiment, they do so in isolation and try multiple iterations. +Unlike traditional software, the users must conduct multiple experiments concurrently with different environments, algorithms, etc. +This may happen when multiple data scientists simultaneously iterate on the same workflow/pipeline. + +The cost of creating an independent infrastructure for each version is enormous and undesirable. +It is beneficial to share the same centralized infrastructure, where the burden of maintaining the infrastructure is with a central infrastructure team, +while the users can use it independently. This improves the cost of operation since the same infrastructure can be reused by multiple teams. + +Versioned workflows help users quickly reproduce prior results or identify the source of previous successful experiments. + +Why Do You Need Versioning? +--------------------------- + +Versioning is required to: + +- Work on the same project concurrently and identify the version/experiment that was successful. +- Capture the environment for a version and independently launch it. +- Visualize prior runs and tie them to experiment results. +- Rollback to production deployments in case of failures with ease. +- Execute multiple experiments in production, which may use different training or data processing algorithms. +- Understand how a specific system evolved and answer questions related to the effectiveness of a specific strategy. + +Operational Benefits of Completely Versioned Workflows/Pipelines +------------------------------------------------------------------- + +The entire workflow in Flyte is versioned and all tasks and entities are immutable which makes it possible to completely change the structure of a workflow between versions, without worrying about the consequences for the pipelines in production. +This hermetic property makes it effortless to manage and deploy new workflow versions and is important for workflows that are long-running. +If a workflow execution is in progress and another new workflow version has been activated, Flyte guarantees that the execution of the old version continues unhindered. + +Consider a scenario where you need to run all the previous executions if there's a bug to be fixed. +Simply fixing the bug in the task may not solve the problem. +Moreover, fixing bugs involves code changes, which may affect the workflow structure. +Flyte addresses this using two properties: + +1. Since the entire workflow is versioned, changing the structure has no impact on the existing execution, and the workflow state won't be corrupted. +2. Flyte provides caching/memoization of outputs. As long as the tasks and their behavior have not changed, it is possible to move them around and still recover their previous outputs, without having to rerun the tasks. This strategy will work even if the workflow changes are in a task. + +Let us take a sample workflow: + +.. mermaid:: + + graph TD; + A-->B; + B-->C; + C-->D; + +In the above graph, let us assume that task `C` fails. It is then possible to simply fix `C` and ``relaunch`` the previous execution (maintaining the inputs etc). This will not re-run tasks ``A``, and ``B`` as long as they are marked as `cache=True`. + +Now, let us consider that the only solution to fix the bug is to change the graph structure and introduce a new step ``B1`` that short circuits the execution to ``D``: + +.. mermaid:: + + graph TD; + A-->B; + B-->B1; + B1-->D; + B1-->C; + C-->D; + +The same ``cache=True`` will handle this complicated situation as well. + +Why Is Versioning Hard? +----------------------- + +Git has become the defacto-standard in version control for code, making it easy to work on branches, merge them, and revert unwanted changes. +But achieving this for a live (running) algorithm usually requires the entire infrastructure to be associated and potentially re-created for every execution. + +How Is Versioning Tied to Reproducibility? +------------------------------------------ + +Workflows can be reproduced without explicit versioning within the system. +To reproduce a past experiment, users need to identify the source code and resurrect any dependencies that the code may have used (for example, TensorFlow 1.x instead of TensorFlow 2.x, or specific Python libraries). +It is also required to instantiate the infrastructure that the previous version may have used. If not recorded, you'll have to ensure that the previously used dataset (say) can be reconstructed. + +This is exactly how Flyte was conceived! + +In Flyte, every task is versioned, and it precisely captures the dependency set. For external tasks, memoization is recommended so that the constructed dataset can be cached on the Flyte side. This way, one can guarantee reproducible behavior from the external systems. + +Moreover, every piece of code is registered with the version of the code that was used to create the instance. +Therefore, users can easily construct the data lineage for all the parts of the workflow. + +What Is the Cost of Versioning & Reproducibility? +------------------------------------------------- + +One of the costs of versioning and allowing on-demand reproducibility is the need to re-instantiate the infrastructure from scratch. +This may sometimes result in additional overhead. However, the advent of Docker containers and Kubernetes has made it possible to build a platform to achieve these goals. + +.. admonition:: Coming soon! + + We are working on reducing the penalty of on-demand infrastructure creation while still maintaining the guarantees. Stay tuned! + +What Is the Best Way to Version Your Tasks and Workflows? +--------------------------------------------------------- + +The best way to version tasks and workflows is to independently version every task with the GIT-SHA or hash of the entire code artifact. +The workflows are also versioned using the GIT-SHA of the containing repository. diff --git a/docs/concepts/workflow_lifecycle.rst b/docs/concepts/workflow_lifecycle.rst new file mode 100644 index 0000000000..efb11e52d8 --- /dev/null +++ b/docs/concepts/workflow_lifecycle.rst @@ -0,0 +1,246 @@ +.. _workflow-lifecycle: + +################################################################# +Understand the Lifecycle of a Flyte Workflow +################################################################# + +.. tags:: Basic, Design + +Let's understand how Flyte's plugin machinery works and how information flows from one component to another in Flyte. + +Under the hood, Flyte relies on a primitive called “Plugins”. Every task that you run on Flyte is powered by a plugin. Some of these plugins are native and guaranteed by Flyte system. These native plugins, for example, run your Flyte tasks inside a k8s pod. There are three native plugins, namely, ``Container``, ``K8sPod``, and ``Sql``. + +Moreover, there are plugins that are actual extensions; they create additional infrastructure and communicate with SaaS on your behalf. Examples include :ref:`Spark `, :ref:`AWS Athena `, etc. + +A plugin requires code to live in multiple locations. + +1. Some parts of plugins logic resides in Flytekit's SDK. This let users define tasks. You can find this logic in Flytekit’s Python (https://github.com/flyteorg/flytekit/tree/master/plugins). Think of this as a client for an RPC service or a web service + +2. Another big chunk of plugins logic lives in + `Flyteplugins `__. This is a library that gets loaded into `FlytePropeller `__. + FlytePropeller (a Kubernetes operator) loads Flyteplugins upon starting. + FlytePropeller is aware of the plugins and their dependency on task execution. + However, FlytePropeller is unaware of how these plugins are executed. + +------------ + +To better Illustrate how things work, lets take for example the “Spark” +plugin and understand what is the sequence of steps that take place for +it to work. + +The Spark plugin lets a user define a task that has access to a Spark Session. +In the background Flyte will provide all the needed infrastructure such that by the time the declared task needs to run, all needed Spark infrastructure is ready and running. + +1. User codes in python a task that uses Spark (See code below) + +.. code:: python + + @task( + task_config=Spark( + spark_conf={ + "spark.driver.memory": "1000M", + "spark.executor.instances": "2", + "spark.driver.cores": "1", + } + ) + ) + def hello_spark(i: int) -> float: + ... + ... + +As mentioned earlier some part of plugin logic lives on the SDK. In this +case think of ``Spark`` data class here as a placeholder for all the +Spark settings that we need our plugin to know. We need to pass this +data across multiple places. This is the config that Flyte operator (Flytepropeller) +will need in order to build the needed spark cluster. ``Spark`` class also tells +Flytekit’s SDK that this task will run as a ``PysparkFunctionTask`` +because ``task_config`` points to a ``Spark`` object instance, this is +clearly illustrated `in spark plugin registration step run in the +background `__ + +2. Once the user has finished writing needed Workflows. A packaging step + is needed before user can run the workflows. This packaging step + transforms workflows and tasks we described in python into a Protobuf + representation. This protobuf representation is used by Flyte across its multiple codebases. For + further details on the protobuf representation check `FlyteIdl + repository `__ . Package step is carried out by the sdk tooling you are using. + +This serialization step will transform our ``hello_spark`` task into a +protobuf representation. It will also transform other tasks, workflows +and launch plans to a protobuf representation. + +Our ``hello_spark`` protobuf representation will look as below. A Task +is serialized as a +`TaskTemplate `__ +as defined in ``FlyteIDL``. + +:: + + Id: Task, "example.example.hello_spark" + Type: "Spark" + Metadata: + runtime: + type: FLYTE_SDK + version: 1.0.3 + flavor: python + + interface: + inputs: + i : + type : simple:Integer + description: "i" + outputs: + o0: + type: FLOAT + description: o0 + custom: + executorpath: "/opt/venv/bin/python3" + mainApplicationFile: /opt/venv/bin/entrypoint.py + sparkConf: + spark.driver.cores: 1 + spark.executor.instances: 2 + spark.driver.memory: 1000M + + + Container: + image: "hello_world:1" + args: + [ + "pyflyte-execute" + "--inputs" + "{{.input}}" + "--output-prefix" + "{{.outputPrefix}}" + "--raw-output-data-prefix" + "{{.rawOutputDataPrefix}}" + "--checkpoint-path" + "{{.checkpointOutputPrefix}}" + "--prev-checkpoint" + "{{.prevCheckpointPrefix}}" + "--resolver" + "flytekit.core.python_auto_container.default_task_resolver" + "--" + "task-module" + "example.example" + "task-name" + "hello_spark" + ] + +This representation is generated within Flytekit. Essentially the SDK is +generating the instructions that Flyte’s kubernetes operator needs to +know in order to run this task at a later stage. + +The ``Type`` field is really important as we will see later this will be +used by Flytepropeller (Kubernetes Operator) to know “how” to execute +this task. + +``Interface`` contains information about what are the inputs and outputs +of our task. Flyte uses this interface to check if tasks are composible. + +``Custom`` is a collection of arbitrary Key/Values, think of it as a +Json dict that any plugin can define as it wishes. In this case the +Spark plugin expects all its particular settings in this field i.e: +Spark workers, driver memory etc. + +`Container `__ +is part of Flyte’s IDL primitives. Essentially any Flyte task is ran as +either three primitives a ``Container`` a ``K8sPod`` or ``Sql``. Every +task contains a ``Target`` which has to be either of these. In this +particular case, our Spark cluster is a ``Container`` target. A +``Container`` specifies all the needed parameters you would in a K8s +ContainerSpec i.e: What docker image to run, what is the command that +will be ran, args etc. + +It is important for the reader to note that Flyte expects to run in a +container that has an entrypoint called ``pyflyte-execute``. This +entrypoint is provided when you ``pip install flytekit``. This +entrypoint and flytekit is what provides a lot of the plumbing logic +inside Flyte. For example It is this entrypoint what automagically +deserializes parquet dataframes an injects them to our task’s functions +if need be. + +It should be clear to the reader that a lot of parameters are surrounded +by ``{}`` these are template variables that are to be rendered at +execution time. + +What is important from this representation is that it contains all the +information that Flyte’s operator needs to know to execute this task: It +is a ``"Spark"`` task, it has a function signature (inputs and outputs), +it tells what docker image to run, and finally, it tells what spark +settings are needed for the cluster. + +For more information on why this task contains these fields check +``TaskTemplate`` in `FlyteIDL +repository `__. +I strongly advice you to take a look at the data structures in this file +as they provide good insight in the interfaces used all across Flyte’s +codebases. + +3. Once user has packaged workflows and tasks then a registration step + is needed. During registration Flyte adds these protocolbuffer files to its + database, essentially making these tasks and workflows runnable for + the user. Registration is done via `Flytectl ` __ + +4. At somepoint a Flyte user will trigger a Workflow run. The workflow + run will start running the defined DAG. Eventually our Spark task + will need to run,. This is where the second step of a plugin kicks + in. Flytepropeller (Kubernetes Operator) will realize that this is a + Task of type ``Spark`` and it will handle it differently. + + - FlytePropeller knows a task is of type Spark, because our ``TaskTemplate`` defined it so ``Type: Spark`` + + - Flyte has a ``PluginRegistry`` which has a dictionary from ``Task Type`` to ``Plugin Handlers``. + + - At run time Flytepropeller will run our task, Flytepropeller will figure out it is a Spark task, and then call the method ``BuildResource`` in Spark's plugin implementation. ``BuildResource`` is a method that each plugin has to implement. + + - `Plugin `__ is a Golang interface providing an important method ``BuildResource`` + + - Spark has its own Plugin defined `here in Flyteplugins repo `__ + +Inside Spark’s +`BuildResource `__ +method is where magic happens. At task runtime: + + - Flytepropeller will call ``BuildResource`` method. This method will ask for the ``Custom`` field, tasks flagged as ``type=Spark`` will have a dictionary containing all sort of Spark settings. + + - Using these settings Flytepropeller will use Spark’s K8s Operator to spawn a spark cluster on the go and run a Spark app (Our python task). + + - The spark app will run a pod with ``pyflyte-execute`` as entrypoint. All the inputs and outputs rendered to what they need to be i.e: paths to the actual data inputs instead of ``{{input}}`` + + - For more information on Spark’s K8s operator see : `SparkApplicationSpec `__ + +5. A pod with entrypoint to ``pyflyte-execute`` execute starts running (Spark App). + + + - ``pyflyte-execute`` provides all the plumbing magic that is needed. In this particular case, It will create a SparkSession and injects it somewhere so that it is ready for when the user defined python’s code starts running. Be aware that this is part of the SDK code (Flytekit). + + - ``pyflyte-execute`` points to `execute_task_cmd `__. + + This entrypoint does a lot of things: + + - Resolves the function that the user wants to run. i.e: where is the needed package where this function lives? . this is what ``"flytekit.core.python_auto_container.default_task_resolver"`` does + + - Downloads needed inputs and do a transformation if need be. I.e: is this a Dataframe? if so we need to transform it into a Pandas DF from parquet. + + - Calls `dispatch_execute `__ . This trigger the execution of our spark task. + + - `PysparkFunctionTask `__. defines what gets run just before the user's task code gets executed. It essentially creatse a spark session and then run the user function (The actual code we want to run!). + +------------ + +Recap +----- + +- Flyte requires coordination between multiple pieces of code. In this + case the SDK and FlytePropeller (K8s operator) +- `Flyte IDL (Interface Language Definition) `__ provides some primitives + for services to talk with each other. Flyte uses Procolbuffer + representations of these primitives +- Three important primitives are : ``Container``, ``K8sPod``, ``Sql``. + At the end of the day all tasks boil down to one of those three. +- github.com/flyteorg/FlytePlugins repository contains all code for plugins: + Spark, AWS Athena, BigQuery… +- Flyte entrypoints are the ones carrying out the heavy lifting: making + sure that inputs are downloaded and/or transformed as needed. +- When running workflows on Flyte, if we want to use Flyte underlying plumbing then + we should include Flyte entrypoints: either Jflyte or Flytekit. diff --git a/docs/concepts/workflows.rst b/docs/concepts/workflows.rst new file mode 100644 index 0000000000..78a3dce3bd --- /dev/null +++ b/docs/concepts/workflows.rst @@ -0,0 +1,51 @@ +.. _divedeep-workflows: + +Workflows +========= + +.. tags:: Basic, Glossary + +A workflow is a directed acyclic graph (DAG) of units of work encapsulated by :ref:`nodes `. +Specific instantiations of a workflow (commonly bound with input arguments) are referred to as **workflow executions**, +or just executions. In other words, a workflow is a template for an ordered task execution. + +Flyte workflows are defined in ``protobuf`` and the flytekit SDK facilitates writing workflows. Users can define workflows as a collection of nodes. +Nodes within a workflow can produce outputs that subsequent nodes could consume as inputs. These dependencies dictate the structure of the workflow. + +Workflows written using the SDK don't need to explicitly define nodes to enclose execution units (tasks, sub-workflows, launch plans); +they will be injected by the SDK and captured at registration time. + +Structure +--------- + +Workflows accept inputs and produce outputs and reuse task definitions across :ref:`projects ` and :ref:`domains `. Every workflow has a default :ref:`launchplan ` with the same name as that of the workflow. + +Workflow structure is flexible because: + +- Nodes can be executed in parallel. +- The same task definition can be re-used within a different workflow. +- A single workflow can contain any combination of task types. +- A workflow can contain a single functional node. +- A workflow can contain multiple nodes in all sorts of arrangements. +- A workflow can launch other workflows. + +At execution time, node executions are triggered as soon as their inputs are available. + +**Workflow nodes naturally run in parallel when possible**. +For example, when a workflow has five independent nodes, i.e., when these five nodes don't consume outputs produced by other nodes, +Flyte runs these nodes in parallel in accordance with the data and resource constraints. + +Flyte-Specific Structure +^^^^^^^^^^^^^^^^^^^^^^^^ + +During :ref:`registration `, Flyte validates the workflow structure and saves the workflow. +The registration process updates the workflow graph. +A compiled workflow will always have a start and end node injected into the workflow graph. +In addition, a failure handler will catch and process execution failures. + +Versioning +---------- + +Like :ref:`tasks `, workflows are versioned too. Registered workflows are immutable, i.e., an instance of a +workflow defined by a specific {Project, Domain, Name, Version} combination can't be updated. +Tasks referenced in a workflow version are immutable and are tied to specific tasks' versions. \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000000..b8581c49bf --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,458 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/stable/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. + +import os +import logging +import sys + +import sphinx.application +import sphinx.errors +from sphinx.util import logging as sphinx_logging + + +sys.path.insert(0, os.path.abspath("../")) +sys.path.append(os.path.abspath("./_ext")) + +sphinx.application.ExtensionError = sphinx.errors.ExtensionError + +# -- Project information ----------------------------------------------------- + +project = "Flyte" +copyright = "2022, Flyte Authors" +author = "Flyte" + +# The short X.Y version +version = "" +# The full version, including alpha/beta/rc tags +release = "1.8.0" + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.napoleon", + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.autosectionlabel", + "sphinx.ext.doctest", + "sphinx.ext.inheritance_diagram", + "sphinx.ext.intersphinx", + "sphinx.ext.graphviz", + "sphinx.ext.todo", + "sphinx.ext.coverage", + "sphinx.ext.ifconfig", + "sphinx.ext.viewcode", + "sphinx.ext.extlinks", + "sphinx-prompt", + "sphinx_copybutton", + "sphinxext.remoteliteralinclude", + "sphinx_issues", + "sphinx_click", + "sphinx_panels", + "sphinxcontrib.mermaid", + "sphinxcontrib.video", + "sphinxcontrib.youtube", + "sphinx_tabs.tabs", + "sphinx_tags", + "myst_nb", + # custom extensions + "auto_examples", + "import_projects", +] + +source_suffix = { + ".rst": "restructuredtext", + ".md": "myst-nb", +} + +extlinks = { + "propeller": ("https://github.com/flyteorg/flytepropeller/tree/master/%s", ""), + "stdlib": ("https://github.com/flyteorg/flytestdlib/tree/master/%s", ""), + "kit": ("https://github.com/flyteorg/flytekit/tree/master/%s", ""), + "plugins": ("https://github.com/flyteorg/flyteplugins/tree/v0.1.4/%s", ""), + "idl": ("https://github.com/flyteorg/flyteidl/tree/v0.14.1/%s", ""), + "admin": ("https://github.com/flyteorg/flyteadmin/tree/master/%s", ""), + "cookbook": ("https://flytecookbook.readthedocs.io/en/latest/", None), +} + + +autosummary_generate = True +suppress_warnings = ["autosectionlabel.*"] +autodoc_typehints = "description" + +# The master toctree document. +master_doc = "index" + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = "en" + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = [ + "_build", + "Thumbs.db", + ".DS_Store", + "auto/**/*.ipynb", + "auto/**/*.py", + "auto/**/*.md", + "examples/**/*.ipynb", + "examples/**/*.py", + "jupyter_execute/**", + "README.md", + "_projects/**", + "_src/**", + "examples/**", + "flytesnacks/index.md", + "flytesnacks/bioinformatics_examples.md", + "flytesnacks/feature_engineering.md", + "flytesnacks/flyte_lab.md", + "flytesnacks/integrations.md", + "flytesnacks/ml_training.md", + "flytesnacks/tutorials.md", + "flytesnacks/userguide.md", + "flytesnacks/README.md", + "flytekit/**/README.md", + "flytekit/_templates/**", + "flytectl/index.rst", + "protos/boilerplate/**", + "protos/tmp/**", + "protos/gen/**", + "protos/docs/**/index.rst", + "protos/index.rst", + "api/flytekit/_templates/**", + "api/flytekit/index.rst", + "reference/index.rst", +] + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_favicon = "images/favicon-flyte-docs.png" +html_logo = "images/favicon-flyte-docs.png" +html_theme = "furo" +html_title = "Flyte" + +templates_path = ["_templates"] + +pygments_style = "tango" +pygments_dark_style = "native" + +html_theme_options = { + "light_css_variables": { + "color-brand-primary": "#4300c9", + "color-brand-content": "#4300c9", + }, + "dark_css_variables": { + "color-brand-primary": "#9D68E4", + "color-brand-content": "#9D68E4", + }, + # custom flyteorg furo theme options + # "github_repo": "flyte", + # "github_username": "flyteorg", + # "github_commit": "master", + # "docs_path": "rsts", # path to documentation source + # "sphinx_gallery_src_dir": "cookbook", # path to directory of sphinx gallery source files relative to repo root + # "sphinx_gallery_dest_dir": "auto", # path to root directory containing auto-generated sphinx gallery examples +} + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] +html_css_files = ["custom.css", "flyte.css"] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {"**": ["logo-text.html", "globaltoc.html", "localtoc.html", "searchbox.html"]} + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = "Flytedoc" + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, "Flyte.tex", "Flyte Documentation", "Flyte Authors", "manual"), +] + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [(master_doc, "flyte", "Flyte Documentation", [author], 1)] + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + master_doc, + "Flyte", + "Flyte Documentation", + author, + "Flyte", + "Accelerate your ML and data workflows to production.", + "Miscellaneous", + ), +] + +# -- Extension configuration ------------------------------------------------- +# autosectionlabel_prefix_document = True +autosectionlabel_maxdepth = 2 + +# Tags config +tags_create_tags = True +tags_extension = ["md", "rst"] +tags_page_title = "Tag" +tags_overview_title = "Pages by Tags" + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +# intersphinx configuration. Uncomment the repeats with the local paths and update your username +# to help with local development. +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "numpy": ("https://numpy.org/doc/stable", None), + "pandas": ("https://pandas.pydata.org/pandas-docs/stable/", None), + "torch": ("https://pytorch.org/docs/master/", None), + "scipy": ("https://docs.scipy.org/doc/scipy/reference", None), + "matplotlib": ("https://matplotlib.org", None), + "pandera": ("https://pandera.readthedocs.io/en/stable/", None), +} + +myst_enable_extensions = ["colon_fence"] + +# Sphinx-mermaid config +mermaid_output_format = "raw" +mermaid_version = "latest" +mermaid_init_js = "mermaid.initialize({startOnLoad:false});" + +# Makes it so that only the command is copied, not the output +copybutton_prompt_text = "$ " + +# prevent css style tags from being copied by the copy button +copybutton_exclude = 'style[type="text/css"]' + +nb_execution_mode = "off" +nb_execution_excludepatterns = [ + "flytekit/**/*", + "flytesnacks/**/*", + "examples/**/*", +] + +# Pattern for removing intersphinx references from source files. +# This should handle cases like: +# +# - :ref:`cookbook:label` -> :ref:`label` +# - :ref:`Text ` -> :ref:`Text
+ + # When using basic authentication, you'll need to specify a scope to the IDP (instead of ``openid``, which is + # only for OAuth). Set that here. + export FLYTE_CREDENTIALS_OAUTH_SCOPES= + + # Set this to force Flytekit to use authentication, even if not required by Admin. This is useful as you're + # rolling out the requirement. + export FLYTE_PLATFORM_AUTH=True + +.. _auth-references: + +********** +References +********** + +This collection of RFCs may be helpful to those who wish to investigate the implementation in more depth. + +* `OAuth2 RFC 6749 `_ +* `OAuth Discovery RFC 8414 `_ +* `PKCE RFC 7636 `_ +* `JWT RFC 7519 `_ + +There's also more detailed information about the authentication flows in the :ref:`deployment-configuration-auth-appendix`. diff --git a/docs/deployment/configuration/cloud_event.rst b/docs/deployment/configuration/cloud_event.rst new file mode 100644 index 0000000000..a168c7801d --- /dev/null +++ b/docs/deployment/configuration/cloud_event.rst @@ -0,0 +1,130 @@ +.. _deployment-configuration-cloud-event: + +############ +Cloud Events +############ + +.. tags:: Infrastructure, AWS, GCP, Advanced + +Progress of Flyte workflow and task execution is delimited by a series of +events that are passed from the FlytePropeller to FlyteAdmin. Administrators +can configure FlyteAdmin to send these `cloud events `_ onwards to a pub/sub system like +SNS/SQS as well. Note that this configuration is distinct from the +configuration for notifications :ref:`deployment-configuration-notifications`, +and :ref:`deployment-configuration-eventing`. +They should use separate topics/queues. These events are meant for external +consumption, outside the Flyte platform. + +********* +Use cases +********* + +CloudEvents is a specification for describing event data in common formats +to provide interoperability across services, platforms and systems. + +The external events flow can be useful for tracking data lineage and +integrating with existing systems within your organization. + +************************* +Supported Implementations +************************* + +Event egress can be configured to work with **AWS** using +`SQS `_ and +`SNS `_, +**GCP** `Cloud Pub/Sub `_, or +`Apache Kafka `_ + +************* +Configuration +************* + +To turn on, add the following to your FlyteAdmin: + +.. tabs:: + + .. tab:: AWS SNS + + .. code:: yaml + + cloud_events.yaml: | + cloudEvents: + enable: true + aws: + region: us-east-2 + eventsPublisher: + eventTypes: + - all # or node, task, workflow + topicName: arn:aws:sns:us-east-2:123456:123-my-topic + type: aws + + .. tab:: GCP Pub/Sub + + .. code:: yaml + + cloud_events.yaml: | + cloudEvents: + enable: true + gcp: + region: us-east-2 + eventsPublisher: + eventTypes: + - all # or node, task, workflow + topicName: my-topic + type: gcp + + .. tab:: Apache Kafka + + .. code:: yaml + + cloud_events.yaml: | + cloudEvents: + enable: true + kafka: + brokers: 127.0.0.1:9092 + eventsPublisher: + eventTypes: + - all + topicName: myTopic + type: kafka + +Helm +====== +There should already be a section for this in the ``values.yaml`` file. Update +the settings under the ``cloud_events`` key and turn ``enable`` to ``true``. +The same flag is used for Helm as for Admin itself. + +***** +Usage +***** + +The events are emitted in cloud Event format, and the data in the cloud event +will be base64 encoded binary representation of the following IDL messages: + +* ``admin_event_pb2.TaskExecutionEventRequest`` +* ``admin_event_pb2.NodeExecutionEventRequest`` +* ``admin_event_pb2.WorkflowExecutionEventRequest`` + +Which of these three events is being sent can be distinguished by the subject +line of the message, which will be one of the three strings above. + +Note that these message wrap the underlying event messages +:std:ref:`found here `. + +CloudEvent Spec +=============== + +.. code:: json + + { + "specversion" : "1.0", + "type" : "com.flyte.resource.workflow", + "source" : "https://github.com/flyteorg/flyteadmin", + "id" : "D234-1234-1234", + "time" : "2018-04-05T17:31:00Z", + "jsonschemaurl": "https://github.com/flyteorg/flyteidl/blob/master/jsonschema/workflow_execution.json", + "data" : "workflow execution event" + } + +.. note:: + The message format may eventually change to an enriched and distinct message type in future releases. diff --git a/docs/deployment/configuration/customizable_resources.rst b/docs/deployment/configuration/customizable_resources.rst new file mode 100644 index 0000000000..1de7664130 --- /dev/null +++ b/docs/deployment/configuration/customizable_resources.rst @@ -0,0 +1,202 @@ +.. _deployment-configuration-customizable-resources: + +################################# +Adding New Customizable Resources +################################# + +.. tags:: Infrastructure, Advanced + +As a quick refresher, custom resources allow you to manage configurations for specific combinations of user projects, domains and workflows that override default values. +Examples of such resources include execution clusters, task resource defaults, and :std:ref:`more `. + +.. note:: + For background on customizable resources, refer to :ref:`deployment-configuration-general`. + +In a :ref:`multi-cluster setup `, an example one could think of is setting routing rules to send certain workflows to specific clusters, which demands setting up custom resources. + +Here's how you could go about building a customizable priority designation. + +Example +------- + +Let's say you want to inject a default priority annotation for your workflows. +Perhaps you start off with a model where everything has a default priority but soon you realize it makes sense that workflows in your production domain should take higher priority than those in your development domain. + +Now, one of your user teams requires critical workflows to have a higher priority than other production workflows. + +Here's how you could do that. + +Flyte IDL +^^^^^^^^^ + +Introduce a new :std:ref:`matchable resource ` that includes a unique enum value and proto message definition. + +For example: + +:: + + enum MatchableResource { + ... + WORKFLOW_PRIORITY = 10; + } + + message WorkflowPriorityAttribute { + int priority = 1; + } + + message MatchingAttributes { + oneof target { + ... + WorkflowPriorityAttribute WorkflowPriority = 11; + } + } + + +See the changes in this `file `__ for an example of what is required. + + +FlyteAdmin +^^^^^^^^^^ + +Once your IDL changes are released, update the logic of FlyteAdmin to `fetch `__ your new matchable priority resource and use it while creating executions or in relevant use cases. + +For example: + +:: + + + resource, err := s.resourceManager.GetResource(ctx, managerInterfaces.ResourceRequest{ + Domain: domain, + Project: project, // optional + Workflow: workflow, // optional, must include project when specifying workflow + LaunchPlan: launchPlan, // optional, must include project + workflow when specifying launch plan + ResourceType: admin.MatchableResource_WORKFLOW_PRIORITY, + }) + + if err != nil { + return err + } + + if resource != nil && resource.Attributes != nil && resource.Attributes.GetWorkflowPriority() != nil { + priorityValue := resource.Attributes.GetWorkflowPriority().GetPriority() + // do something with the priority here + } + + +Flytekit +^^^^^^^^ + +For convenience, add a FlyteCTL wrapper to update the new attributes. Refer to `this PR `__ for the entire set of changes required. + +That's it! You now have a new matchable attribute to configure as the needs of your users evolve. + +Flyte ResourceManager +--------------------- + +**Flyte ResourceManager** is a configurable component that allows plugins to manage resource allocations independently. It helps track resource utilization of tasks that run on Flyte. The default deployments are configured as ``noop``, which indicates that the ResourceManager provided by Flyte is disabled and plugins rely on each independent platform to manage resource utilization. In situations like the K8s plugin, where the platform has a robust mechanism to manage resource scheduling, this may work well. However, in a scenario like a simple web API plugin, the rate at which Flyte sends requests may overwhelm a service and benefit from additional resource management. + +The below attribute is configurable within FlytePropeller, which can be disabled with: + +.. code-block:: yaml + + resourcemanager: + type: noop + +The ResourceManager provides a task-type-specific pooling system for Flyte tasks. Optionally, plugin writers can request resource allocation in their tasks. + +A plugin defines a collection of resource pools using its configuration. Flyte uses tokens as a placeholder to represent a unit of resource. + +How does a Flyte plugin request for resources? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Flyte plugin registers the resource and the desired quota of every resource with the **ResourceRegistrar** when setting up FlytePropeller. When a plugin is invoked, FlytePropeller provides a proxy for the plugin. This proxy facilitates the plugin's view of the resource pool by controlling operations to allocate and deallocate resources. + +.. dropdown:: :fa:`info-circle` Enabling Redis instance + :title: text-muted + :animate: fade-in-slide-down + + The ResourceManager can use a Redis instance as an external store to track and manage resource pool allocation. By default, it is disabled, and can be enabled with: + + .. code-block:: yaml + + resourcemanager: + type: redis + resourceMaxQuota: 100 + redis: + hostPaths: + - foo + hostKey: bar + maxRetries: 0 + +Once the setup is complete, FlytePropeller builds a ResourceManager based on the previously requested resource registration. Based on the plugin implementation's logic, resources are allocated and deallocated. + +During runtime, the ResourceManager: + +#. Allocates tokens to the plugin. +#. Releases tokens once the task is completed. + +How are resources allocated? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When a Flyte task execution needs to send a request to an external service, the plugin claims a unit of the corresponding resource. This is done using a **ResourceName**, which is a unique token and a fully qualified resource request (which is typically an integer). The execution generates this unique token and registers this token with the ResourceManager by calling the ResourceManager’s **"AllocateResource function"**. If the resource pool has sufficient capacity to fulfil your request, then the resources requested are allocated, and the plugin proceeds further. + +When the status is **"AllocationGranted"**, the execution moves forward and sends out the request for those resources. + +The granted token is recorded in a token pool which corresponds to the resource that is managed by the ResourceManager. + +How are resources deallocated? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +When the request is completed, the plugin asks the ResourceManager to release the token by calling the ReleaseResource() function present in the ResourceManager. Upon calling the function, the token is eliminated from the token pool. +In this manner, Flyte plugins intelligently throttle resource usage during parallel execution of nodes. + +Example +^^^^^^^^ +Let's take an example to understand resource allocation and deallocation when a plugin requests resources. + +Flyte has a built-in `Qubole `__ plugin. This plugin allows Flyte tasks to send Hive commands to Qubole. In the plugin, a single Qubole cluster is considered a resource, and sending a single Hive command to a Qubole cluster consumes a token of the corresponding resource. +The resource is allocated when the status is **“AllocationGranted”**. Qubole plugin calls: + +.. code-block:: go + + status, err := AllocateResource(ctx, , , ) + +Wherein the placeholders are occupied by: + +.. code-block:: go + + status, err := AllocateResource(ctx, "default_cluster", "flkgiwd13-akjdoe-0", ResourceConstraintsSpec{}) + +The resource is deallocated when the Hive command completes its execution and the corresponding token is released. The plugin calls: + +.. code-block:: go + + status, err := AllocateResource(ctx, , , ) + +Wherein the placeholders are occupied by: + +.. code-block:: go + + err := ReleaseResource(ctx, "default_cluster", "flkgiwd13-akjdoe-0") + +Below is an example interface that shows allocation and deallocation of resources. + +.. code-block:: go + + type ResourceManager interface { + GetID() string + // During execution, the plugin calls AllocateResource() to register a token in the token pool associated with a resource + // If it is granted an allocation, the token is recorded in the token pool until the same plugin releases it. + // When calling AllocateResource, the plugin has to specify a ResourceConstraintsSpec that contains resource capping constraints at different project and namespace levels. + // The ResourceConstraint pointers in ResourceConstraintsSpec can be set to nil to not have a constraint at that level + AllocateResource(ctx context.Context, namespace ResourceNamespace, allocationToken string, constraintsSpec ResourceConstraintsSpec) (AllocationStatus, error) + // During execution, after an outstanding request is completed, the plugin uses ReleaseResource() to release the allocation of the token from the token pool. This way, it redeems the quota taken by the token + ReleaseResource(ctx context.Context, namespace ResourceNamespace, allocationToken string) error + } + +How can you force ResourceManager to force runtime quota allocation constraints? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Runtime quota allocation constraints can be achieved using ResourceConstraintsSpec. It is a contact that a plugin can specify at different project and namespace levels. + +Let's take an example to understand it. + +You can set ResourceConstraintsSpec to ``nil`` objects, which means there would be no allocation constraints at the respective project and namespace level. When ResourceConstraintsSpec specifies ``nil`` ProjectScopeResourceConstraint, and a non-nil NamespaceScopeResourceConstraint, it suggests no constraints specified at any project or namespace level. diff --git a/docs/deployment/configuration/eventing.rst b/docs/deployment/configuration/eventing.rst new file mode 100644 index 0000000000..be64d6f2f1 --- /dev/null +++ b/docs/deployment/configuration/eventing.rst @@ -0,0 +1,64 @@ +.. _deployment-configuration-eventing: + +############### +Platform Events +############### + +.. tags:: Configuration, Infrastructure, Advanced + +Progress of Flyte workflow and task execution is delimited by a series of events that are passed from the FlytePropeller to FlyteAdmin. +Administrators can configure FlyteAdmin to send these events onwards to a pub/sub system like SNS/SQS as well. Note that this configuration is distinct from the configuration for notifications :ref:`deployment-configuration-notifications`. They should use separate topics/queues. These events are meant for external consumption, outside the Flyte platform, whereas the notifications pub/sub setup is entirely for Admin itself to send email/pagerduty/etc notifications. + +********* +Use cases +********* + +The external events flow can be useful for tracking data lineage and integrating with existing systems within your organization. + +************************* +Supported Implementations +************************* + +Event egress can be configured to work with **AWS** using `SQS `_ and `SNS `_ or **GCP** `Cloud Pub/Sub `_. + +************* +Configuration +************* + +To turn on, add the following to your FlyteAdmin: + +.. code:: yaml + + external_events.yaml: | + externalEvents: + enable: true + aws: + region: us-east-2 + eventsPublisher: + eventTypes: + - all + topicName: arn:aws:sns:us-east-2:123456:123-my-topic + type: aws + +Helm +==== + +There should already be a section for this in the ``values.yaml`` file. +Update the settings under the ``external_events`` key and turn ``enable`` to ``true``. The same flag is used for Helm as for Admin itself. + +***** +Usage +***** + +The events emitted will be base64 encoded binary representation of the following IDL messages: + +* ``admin_event_pb2.TaskExecutionEventRequest`` +* ``admin_event_pb2.NodeExecutionEventRequest`` +* ``admin_event_pb2.WorkflowExecutionEventRequest`` + +Which of these three events is being sent can be distinguished by the subject line of the message, which will be one of the three strings above. + +Note that these message wrap the underlying event messages :std:ref:`found here `. + +.. note:: + The message format may eventually change to an enriched and distinct message type in future releases. diff --git a/docs/deployment/configuration/general.rst b/docs/deployment/configuration/general.rst new file mode 100644 index 0000000000..3cd1db0f12 --- /dev/null +++ b/docs/deployment/configuration/general.rst @@ -0,0 +1,740 @@ +.. _deployment-configuration-general: + +################################# +Configuring Custom K8s Resources +################################# + +*************************** +Configurable Resource Types +*************************** + +Many platform specifications such as task resource defaults, project namespace Kubernetes quota, and more can be +assigned using default values or custom overrides. Defaults are specified in the FlyteAdmin config and +overrides for specific projects are registered with the FlyteAdmin service. + +You can customize these settings along increasing levels of specificity with Flyte: + +- Domain +- Project and Domain +- Project, Domain, and Workflow name +- Project, Domain, Workflow name and LaunchPlan name + +See :ref:`control-plane` to understand projects and domains. +The following section will show you how to configure the settings along +these dimensions. + +Task Resources +============== + +Configuring task :py:class:`resources ` includes +setting default values for unspecified task requests and limits. Task resources +also include limits which specify the maximum value that a task request or a limit can have. + +- CPU +- GPU +- Memory +- Storage +- `Ephemeral Storage `__ + +In the absence of an override, the global +`default values `__ +in `task_resource_defaults` are used. + +The override values from the database are assigned at execution, rather than registration time. + +To customize resources for project-domain attributes, define a ``tra.yaml`` file with your overrides: + +.. code-block:: yaml + + project: flyteexamples + domain: development + defaults: + cpu: "1" + memory: 150Mi + limits: + cpu: "2" + memory: 450Mi + +Update the task resource attributes for a project-domain combination: + +.. prompt:: bash $ + + flytectl update task-resource-attribute --attrFile tra.yaml + +.. note:: + + Refer to the :ref:`docs ` to + learn more about the command and its supported flag(s). + +To fetch and verify the individual project-domain attributes: + +.. prompt:: bash $ + + flytectl get task-resource-attribute -p flyteexamples -d development + +.. note:: + + Refer to the :ref:`docs ` to learn + more about the command and its supported flag(s). + +You can view all custom task-resource-attributes by visiting +``protocol://`` and substitute +the protocol and host appropriately. + +Cluster Resources +================= +These are free-form key-value pairs used when filling the templates that the +admin feeds into the cluster manager, which is the process that syncs Kubernetes +resources. + +The keys represent templatized variables in the +`cluster resource template `__ +and the values are what you want to see filled in. + +In the absence of custom override values, you can use ``templateData`` from the +`FlyteAdmin config `__ +as a default. Flyte specifies these defaults by domain and applies them to every +project-domain namespace combination. + +.. note:: + The settings above can be specified on domain, and project-and-domain. + Since Flyte hasn't tied the notion of a workflow or a launch plan to any Kubernetes construct, specifying a workflow or launch plan name doesn't make sense. + This is a departure from the usual hierarchy for customizable resources. + +Define an attributes file, ``cra.yaml``: + +.. code-block:: yaml + + domain: development + project: flyteexamples + attributes: + projectQuotaCpu: "1000" + projectQuotaMemory: 5Ti + +To ensure that the overrides reflect in the Kubernetes namespace +``flyteexamples-development`` (that is, the namespace has a resource quota of +1000 CPU cores and 5TB of memory) when the admin fills in cluster resource +templates: + +.. prompt:: bash $ + + flytectl update cluster-resource-attribute --attrFile cra.yaml + +.. note:: + + Refer to the :ref:`docs ` + to learn more about the command and its supported flag(s). + +To fetch and verify the individual project-domain attributes: + +.. prompt:: bash $ + + flytectl get cluster-resource-attribute -p flyteexamples -d development + +.. note:: + + Refer to the :ref:`docs ` to + learn more about the command and its supported flag(s). + +Flyte uses these updated values to fill the template fields for the +``flyteexamples-development`` namespace. + +For other namespaces, the +`platform defaults `__ +apply. + +.. note:: + The template values, for example, ``projectQuotaCpu`` or ``projectQuotaMemory`` are free-form strings. + Ensure that they match the template placeholders in your `template file `__ + for your changes to take effect and custom values to be substituted. + +You can view all custom cluster-resource-attributes by visiting ``protocol://`` +and substitute the protocol and host appropriately. + +Execution Cluster Label +======================= +This allows forcing a matching execution to consistently execute on a specific +Kubernetes cluster for multi-cluster Flyte deployment set-up. + +Define an attributes file in `ec.yaml`: + +.. code-block:: yaml + + value: mycluster + domain: development + project: flyteexamples + +Ensure that admin places executions in the flyteexamples project and development domain onto ``mycluster``: + +.. prompt:: bash $ + + flytectl update execution-cluster-label --attrFile ec.yaml + +.. note:: + + Refer to the :ref:`docs ` + to learn more about the command and its supported flag(s). + +To fetch and verify the individual project-domain attributes: + +.. prompt:: bash $ + + flytectl get execution-cluster-label -p flyteexamples -d development + +.. note:: + + Refer to the :ref:`docs ` to + learn more about the command and its supported flag(s). + +You can view all custom execution cluster attributes by visiting +``protocol://`` and substitute +the protocol and host appropriately. + +Execution Queues +================ +Execution queues are defined in +`flyteadmin config `__. +These are used for execution placement for constructs like AWS Batch. + +The **attributes** associated with an execution queue must match the **tags** +for workflow executions. The tags associated with configurable resources are +stored in the admin database. + +.. prompt:: bash $ + + flytectl update execution-queue-attribute + +.. note:: + + Refer to the :ref:`docs ` + to learn more about the command and its supported flag(s). + +You can view existing attributes for which tags can be assigned by visiting +``protocol:///api/v1/matchable_attributes?resource_type=2`` and substitute +the protocol and host appropriately. + +Workflow Execution Config +========================= + +This helps with overriding the config used for workflows execution which includes +`security context `__, `annotations or labels `__ +etc. in the `Workflow execution config `__. +These can be defined at two levels of project-domain or project-domain-workflow: + +.. prompt:: bash $ + + flytectl update workflow-execution-config + +.. note:: + + Refer to the :ref:`docs ` + to learn more about the command and its supported flag(s). + +Configuring Service Roles +========================= +You can configure service roles along 3 levels: + +#. Project + domain defaults (every execution launched in this project/domain uses this service account) + +#. Launch plan default (every invocation of this launch plan uses this service account) + +#. Execution time override (overrides at invocation for a specific execution only) + +********* +Hierarchy +********* + +Increasing specificity defines how matchable resource attributes get applied. +The available configurations, in order of decreasing specificity are: + +#. Domain, Project, Workflow name, and LaunchPlan + +#. Domain, Project, and Workflow name + +#. Domain and Project + +#. Domain + +Default values for all and per-domain attributes may be specified in the +FlyteAdmin config as documented in the :std:ref:`deployment-configuration-customizable-resources`. + +Example +======= +If the database includes the following: + ++------------+--------------+----------+-------------+-----------+ +| Domain | Project | Workflow | Launch Plan | Tags | ++============+==============+==========+=============+===========+ +| production | widgetmodels | | | critical | ++------------+--------------+----------+-------------+-----------+ +| production | widgetmodels | Demand | | supply | ++------------+--------------+----------+-------------+-----------+ + +- Any inbound ``CreateExecution`` requests with **[Domain: Production, Project: widgetmodels, Workflow: Demand]** for any launch plan will have a tag value of "supply". +- Any inbound ``CreateExecution`` requests with **[Domain: Production, Project: widgetmodels]** for any workflow other than ``Demand`` and any launch plan will have a tag value "critical". +- All other inbound CreateExecution requests will use the default values specified in the FlyteAdmin config (if any). + + +Configuring K8s Pod +=================== + +There are two approaches to applying the K8s Pod configuration. The **recommended** +method is to use Flyte's Compile-time and Runtime PodTemplate schemes. You can do this by creating +K8s PodTemplate resource/s that serves as the base configuration for all the +task Pods that Flyte initializes. This solution ensures completeness regarding +support configuration options and maintainability as new features are added to K8s. + +The legacy technique is to set configuration options in Flyte's K8s plugin configuration. + +.. note :: + + These two approaches can be used simultaneously, where the K8s plugin configuration will override the default PodTemplate values. + +.. _using-k8s-podtemplates: + +******************************* +Using K8s PodTemplates +******************************* + +`PodTemplate `__ +is a K8s native resource used to define a K8s Pod. It contains all the fields in +the PodSpec, in addition to ObjectMeta to control resource-specific metadata +such as Labels or Annotations. They are commonly applied in Deployments, +ReplicaSets, etc to define the managed Pod configuration of the resources. + +Within Flyte, you can leverage this resource to configure Pods created as part +of Flyte's task execution. It ensures complete control over Pod configuration, +supporting all options available through the resource and ensuring maintainability +in future versions. + +Starting with the Flyte 1.4 release, we now have 2 ways of defining `PodTemplate `__: +1. Compile-time PodTemplate defined at the task level +2. Runtime PodTemplates + + +Compile-time PodTemplates +========================= + +We can define a compile-time pod template, as part of the definition of a `Task `__, for example: + +.. code-block:: python + + @task( + pod_template=PodTemplate( + primary_container_name="primary", + labels={"lKeyA": "lValA", "lKeyB": "lValB"}, + annotations={"aKeyA": "aValA", "aKeyB": "aValB"}, + pod_spec=V1PodSpec( + containers=[ + V1Container( + name="primary", + image="repo/placeholderImage:0.0.0", + command="echo", + args=["wow"], + resources=V1ResourceRequirements(limits={"cpu": "999", "gpu": "999"}), + env=[V1EnvVar(name="eKeyC", value="eValC"), V1EnvVar(name="eKeyD", value="eValD")], + ), + ], + volumes=[V1Volume(name="volume")], + tolerations=[ + V1Toleration( + key="num-gpus", + operator="Equal", + value=1, + effect="NoSchedule", + ), + ], + ) + ) + ) + def t1() -> int: + ... + +Notice how in this example we are defining a new PodTemplate inline, which allows us to define a full +`V1PodSpec `__ and also define +the name of the primary container, labels, and annotations. + +The term compile-time here refers to the fact that the pod template definition is part of the `TaskSpec `__. + +Runtime PodTemplates +==================== + +Runtime PodTemplates, as the name suggests, are applied during runtime, as part of building the resultant Pod. In terms of how +they are applied, you have two choices: (1) you either elect one specific PodTemplate to be considered as default, or (2) you +define a PodTemplate name and use that in the declaration of the task. Those two options are mutually exclusive, meaning that +in the situation where a default PodTemplate is set and a PodTemplate name is present in the task definition, only the +PodTemplate name will be used. + + +Set the ``default-pod-template-name`` in FlytePropeller +-------------------------------------------------------- + +This `option `__ +initializes a K8s informer internally to track system PodTemplate updates +(creates, updates, etc) so that FlytePropeller is +`aware `__ +of the latest PodTemplate definitions in the K8s environment. You can find this +setting in `FlytePropeller `__ +config map, which is not set by default. + +An example configuration is: + +.. code-block:: yaml + + plugins: + k8s: + co-pilot: + name: "flyte-copilot-" + image: "cr.flyte.org/flyteorg/flytecopilot:v0.0.15" + start-timeout: "30s" + default-pod-template-name: + +Create a PodTemplate resource +------------------------------ + +Flyte recognizes PodTemplate definitions with the ``default-pod-template-name`` at two granularities. + +1. A system-wide configuration can be created in the same namespace that + FlytePropeller is running in (typically `flyte`). +2. PodTemplates can be applied from the same namespace that the Pod will be + created in. FlytePropeller always favors the PodTemplate with the more + specific namespace. For example, a Pod created in the ``flytesnacks-development`` + namespace will first look for a PodTemplate from the ``flytesnacks-development`` + namespace. If that PodTemplate doesn't exist, it will look for a PodTemplate + in the same namespace that FlytePropeller is running in (in our example, ``flyte``), + and if that doesn't exist, it will begin configuration with an empty PodTemplate. + +Flyte configuration supports all the fields available in the PodTemplate +resource, including container-level configuration. Specifically, containers may +be configured at two granularities, namely "default" and "primary". + +In this scheme, if the default PodTemplate contains a container with the name +"default", that container will be used as the base configuration for all +containers Flyte constructs. Similarly, a container named "primary" will be used +as the base container configuration for all primary containers. If both container +names exist in the default PodTemplate, Flyte first applies the default +configuration, followed by the primary configuration. + +The ``containers`` field is required in each k8s PodSpec. If no default +configuration is desired, specifying a container with a name other than "default" +or "primary" (for example, "noop") is considered best practice. Since Flyte only +processes the "default" or "primary" containers, this value will always be dropped +during Pod construction. Similarly, each k8s container is required to have an +``image``. This value will always be overridden by Flyte, so this value may be +set to anything. However, we recommend using a real image, for example +``docker.io/rwgrim/docker-noop``. + +Using ``pod_template_name`` in a Task +-------------------------------------- + +It's also possible to use PodTemplate in tasks by specifying ``pod_template_name`` in the task definition. For example: + +.. code-block:: python + + @task( + pod_template_name="a_pod_template", + ) + def t1() -> int: + ... + +In this example we're specifying that a previously created Runtime PodTemplate resource named ``a_pod_template`` is going to be applied. +The only requirement is that this PodTemplate exists at the moment this task is about to be executed. + + +********************************* +Flyte's K8s Plugin Configuration +********************************* + +The FlytePlugins repository defines `configuration `__ +for the Flyte K8s Plugin. They contain a variety of common options for Pod configuration +which are applied when constructing a Pod. Typically, these options map one-to-one +with K8s Pod fields. This makes it difficult to maintain configuration options as K8s +versions change and fields are added/deprecated. + +********************************* +Evaluation Order in PodTemplates +********************************* + +The following diagram shows the precedence in evaluation order between the different types of PodTemplates and K8s Plugin Configuration. The precedence is higher at the top and decreases as the height of the tree increases. + +.. mermaid:: + :alt: Evaluation order of PodTemplates + + graph BT + B["@task pod_template"] --> A["k8s plugin"] + C["runtime PodTemplate"] --> B + D["@task pod_template_name"] --> B + + +To better understand how Flyte constructs task execution Pods based on Compile-time and Runtime PodTemplates, +and K8s plugin configuration options, let's take a few examples. + +Example 1: Runtime PodTemplate and K8s Plugin Configuration +=========================================================== + +If you have a Runtime PodTemplate defined in the ``flyte`` namespace +(where FlytePropeller instance is running), then it is applied to all Pods that +Flyte creates, unless a **more specific** PodTemplate is defined in the namespace +where you start the Pod. + +An example PodTemplate is shown: + +.. code-block:: yaml + + apiVersion: v1 + kind: PodTemplate + metadata: + name: flyte-template + namespace: flyte + template: + metadata: + labels: + - foo + annotations: + - foo: initial-value + - bar: initial-value + spec: + containers: + - name: default + image: docker.io/rwgrim/docker-noop + terminationMessagePath: "/dev/foo" + hostNetwork: false + +In addition, the K8s plugin configuration in FlytePropeller defines the default +Pod Labels, Annotations, and enables the host networking. + +.. code-block:: yaml + + plugins: + k8s: + default-labels: + - bar + default-annotations: + - foo: overridden-value + - baz: non-overridden-value + enable-host-networking-pod: true + +To construct a Pod, FlytePropeller initializes a Pod definition using the default +PodTemplate. This definition is applied to the K8s plugin configuration values, +and any task-specific configuration is overlaid. During the process, when lists +are merged, values are appended and when maps are merged, the values are overridden. +The resultant Pod using the above default PodTemplate and K8s Plugin configuration is shown: + +.. code-block:: yaml + + apiVersion: v1 + kind: Pod + metadata: + name: example-pod + namespace: flytesnacks-development + labels: + - foo // maintained initial value + - bar // value appended by k8s plugin configuration + annotations: + - foo: overridden-value // value overridden by k8s plugin configuration + - bar: initial-value // maintained initial value + - baz: non-overridden-value // value added by k8s plugin configuration + spec: + containers: + - name: ax9kd5xb4p8r45bpdv7v-n0-0 + image: ghcr.io/flyteorg/flytecookbook:core-bfee7e549ad749bfb55922e130f4330a0ebc25b0 + terminationMessagePath: "/dev/foo" + // remaining container configuration omitted + hostNetwork: true // overridden by the k8s plugin configuration + +The last step in constructing a Pod is to apply any task-specific configuration. +These options follow the same rules as merging the default PodTemplate and K8s +Plugin configuration (that is, list appends and map overrides). Task-specific +options are intentionally robust to provide fine-grained control over task +execution in diverse use-cases. Therefore, exploration is beyond this scope +and has therefore been omitted from this documentation. + +Example 2: A Runtime and Compile-time PodTemplates +================================================== + +In this example we're going to have a Runtime PodTemplate and a Compile-time PodTemplate defined in a task. + +Let's say we have this Runtime PodTemplate defined in the same namespace as the one used to kick off an execution +of the task. For example: + +.. code-block:: yaml + + apiVersion: v1 + kind: PodTemplate + metadata: + name: flyte-template + namespace: flytesnacks-development + template: + metadata: + annotations: + - annotation_1: initial-value + - bar: initial-value + spec: + containers: + - name: default + image: docker.io/rwgrim/docker-noop + terminationMessagePath: "/dev/foo" + +And the definition of the Compile-time PodTemplate in a task: + +.. code-block:: python + + @task( + pod_template=PodTemplate( + primary_container_name="primary", + labels={ + "label_1": "value-1", + "label_2": "value-2", + }, + annotations={ + "annotation_1": "value-1", + "annotation_2": "value-2", + }, + pod_spec=V1PodSpec( + containers=[ + V1Container( + name="primary", + image="a.b.c/image:v1", + command="cmd", + args=[], + ), + ], + ) + ) + ) + def t1() -> int: + ... + +The resultant Pod is as follows: + +.. code-block:: yaml + + apiVersion: v1 + kind: Pod + metadata: + name: example-pod + namespace: flytesnacks-development + labels: + - label_1: value-1 # from Compile-time value + - label_2: value-2 # from Compile-time value + annotations: + - annotation_1: value-1 # value overridden by Compile-time PodTemplate + - annotation_2: value-2 # from Compile-time PodTemplate + - bar: initial-value # from Runtime PodTemplate + spec: + containers: + - name: default + image: docker.io/rwgrim/docker-noop + terminationMessagePath: "/dev/foo" + - name: primary + image: a.b.c/image:v1 + command: cmd + args: [] + // remaining container configuration omitted + +Notice how options follow the same merging rules, i.e. lists append and maps override. + + +Example 3: Runtime and Compile-time PodTemplates and K8s Plugin Configuration +============================================================================= + +Now let's make a slightly more complicated example where now we have both Compile-time and Runtime PodTemplates being combined +with K8s Configuration. + +Here's the definition of a Compile-time PodTemplate: + +.. code-block:: python + + @task( + pod_template=PodTemplate( + primary_container_name="primary", + labels={ + "label_1": "value-compile", + "label_2": "value-compile", + }, + annotations={ + "annotation_1": "value-compile", + "annotation_2": "value-compile", + }, + pod_spec=V1PodSpec( + containers=[ + V1Container( + name="primary", + image="a.b.c/image:v1", + command="cmd", + args=[], + ), + ], + host_network=True, + ) + ) + ) + def t1() -> int: + ... + + +And a Runtime PodTemplate: + +.. code-block:: yaml + + apiVersion: v1 + kind: PodTemplate + metadata: + name: flyte-template + namespace: flyte + template: + metadata: + labels: + - label_1: value-runtime + - label_2: value-runtime + - label_3: value-runtime + annotations: + - foo: value-runtime + - bar: value-runtime + spec: + containers: + - name: default + image: docker.io/rwgrim/docker-noop + terminationMessagePath: "/dev/foo" + hostNetwork: false + +And the following K8s Plugin Configuration: + +.. code-block:: yaml + + plugins: + k8s: + default-labels: + - label_1: value-plugin + default-annotations: + - annotation_1: value-plugin + - baz: value-plugin + +The resultant pod for that task is as follows: + +.. code-block:: yaml + + apiVersion: v1 + kind: Pod + metadata: + name: example-pod + namespace: flytesnacks-development + labels: + - label_1: value-plugin + - label_2: value-compile + annotations: + - annotation_1: value-plugin + - annotation_2: value-compile + - foo: value-runtime + - bar: value-runtime + - baz: value-plugin + spec: + containers: + - name: default + image: docker.io/rwgrim/docker-noop + terminationMessagePath: "/dev/foo" + - name: primary + image: a.b.c/image:v1 + command: cmd + args: [] + // remaining container configuration omitted diff --git a/docs/deployment/configuration/generated/datacatalog_config.rst b/docs/deployment/configuration/generated/datacatalog_config.rst new file mode 100644 index 0000000000..b20aa7fe59 --- /dev/null +++ b/docs/deployment/configuration/generated/datacatalog_config.rst @@ -0,0 +1,925 @@ +.. _flytedatacatalog-config-specification: + +######################################### +Flyte Datacatalog Configuration +######################################### + +- `application <#section-application>`_ + +- `database <#section-database>`_ + +- `datacatalog <#section-datacatalog>`_ + +- `logger <#section-logger>`_ + +- `storage <#section-storage>`_ + +Section: application +======================================================================================================================== + +grpcPort (int) +------------------------------------------------------------------------------------------------------------------------ + +On which grpc port to serve Catalog + +**Default Value**: + +.. code-block:: yaml + + "8081" + + +grpcServerReflection (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable GRPC Server Reflection + +**Default Value**: + +.. code-block:: yaml + + "true" + + +httpPort (int) +------------------------------------------------------------------------------------------------------------------------ + +On which http port to serve Catalog + +**Default Value**: + +.. code-block:: yaml + + "8080" + + +secure (bool) +------------------------------------------------------------------------------------------------------------------------ + +Whether to run Catalog in secure mode or not + +**Default Value**: + +.. code-block:: yaml + + "false" + + +readHeaderTimeoutSeconds (int) +------------------------------------------------------------------------------------------------------------------------ + +The amount of time allowed to read request headers. + +**Default Value**: + +.. code-block:: yaml + + "32" + + +Section: database +======================================================================================================================== + +host (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +port (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +dbname (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +username (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +password (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +passwordPath (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +options (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +debug (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +enableForeignKeyConstraintWhenMigrating (bool) +------------------------------------------------------------------------------------------------------------------------ + +Whether to enable gorm foreign keys when migrating the db + +**Default Value**: + +.. code-block:: yaml + + "false" + + +maxIdleConnections (int) +------------------------------------------------------------------------------------------------------------------------ + +maxIdleConnections sets the maximum number of connections in the idle connection pool. + +**Default Value**: + +.. code-block:: yaml + + "10" + + +maxOpenConnections (int) +------------------------------------------------------------------------------------------------------------------------ + +maxOpenConnections sets the maximum number of open connections to the database. + +**Default Value**: + +.. code-block:: yaml + + "100" + + +connMaxLifeTime (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +sets the maximum amount of time a connection may be reused + +**Default Value**: + +.. code-block:: yaml + + 1h0m0s + + +postgres (`database.PostgresConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + dbname: postgres + debug: false + host: postgres + options: sslmode=disable + password: "" + passwordPath: "" + port: 5432 + username: postgres + + +sqlite (`database.SQLiteConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + file: "" + + +config.Duration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Duration (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 1h0m0s + + +database.PostgresConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +host (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The host name of the database server + +**Default Value**: + +.. code-block:: yaml + + postgres + + +port (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The port name of the database server + +**Default Value**: + +.. code-block:: yaml + + "5432" + + +dbname (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The database name + +**Default Value**: + +.. code-block:: yaml + + postgres + + +username (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The database user who is connecting to the server. + +**Default Value**: + +.. code-block:: yaml + + postgres + + +password (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The database password. + +**Default Value**: + +.. code-block:: yaml + + "" + + +passwordPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Points to the file containing the database password. + +**Default Value**: + +.. code-block:: yaml + + "" + + +options (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +See http://gorm.io/docs/connecting_to_the_database.html for available options passed, in addition to the above. + +**Default Value**: + +.. code-block:: yaml + + sslmode=disable + + +debug (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Whether or not to start the database connection with debug mode enabled. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +database.SQLiteConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +file (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The path to the file (existing or new) where the DB should be created / stored. If existing, then this will be re-used, else a new will be created + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: datacatalog +======================================================================================================================== + +storage-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +StoragePrefix specifies the prefix where DataCatalog stores offloaded ArtifactData in CloudStorage. If not specified, the data will be stored in the base container directly. + +**Default Value**: + +.. code-block:: yaml + + metadata + + +metrics-scope (string) +------------------------------------------------------------------------------------------------------------------------ + +Scope that the metrics will record under. + +**Default Value**: + +.. code-block:: yaml + + datacatalog + + +profiler-port (int) +------------------------------------------------------------------------------------------------------------------------ + +Port that the profiling service is listening on. + +**Default Value**: + +.. code-block:: yaml + + "10254" + + +heartbeat-grace-period-multiplier (int) +------------------------------------------------------------------------------------------------------------------------ + +Number of heartbeats before a reservation expires without an extension. + +**Default Value**: + +.. code-block:: yaml + + "3" + + +max-reservation-heartbeat (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +The maximum available reservation extension heartbeat interval. + +**Default Value**: + +.. code-block:: yaml + + 10s + + +Section: logger +======================================================================================================================== + +show-source (bool) +------------------------------------------------------------------------------------------------------------------------ + +Includes source code location in logs. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +mute (bool) +------------------------------------------------------------------------------------------------------------------------ + +Mutes all logs regardless of severity. Intended for benchmarks/tests only. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +level (int) +------------------------------------------------------------------------------------------------------------------------ + +Sets the minimum logging level. + +**Default Value**: + +.. code-block:: yaml + + "3" + + +formatter (`logger.FormatterConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets logging format. + +**Default Value**: + +.. code-block:: yaml + + type: json + + +logger.FormatterConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets logging format type. + +**Default Value**: + +.. code-block:: yaml + + json + + +Section: storage +======================================================================================================================== + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +Sets the type of storage to configure [s3/minio/local/mem/stow]. + +**Default Value**: + +.. code-block:: yaml + + s3 + + +connection (`storage.ConnectionConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + access-key: "" + auth-type: iam + disable-ssl: false + endpoint: "" + region: us-east-1 + secret-key: "" + + +stow (`storage.StowConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Storage config for stow backend. + +**Default Value**: + +.. code-block:: yaml + + {} + + +container (string) +------------------------------------------------------------------------------------------------------------------------ + +Initial container (in s3 a bucket) to create -if it doesn't exist-.' + +**Default Value**: + +.. code-block:: yaml + + "" + + +enable-multicontainer (bool) +------------------------------------------------------------------------------------------------------------------------ + +If this is true, then the container argument is overlooked and redundant. This config will automatically open new connections to new containers/buckets as they are encountered + +**Default Value**: + +.. code-block:: yaml + + "false" + + +cache (`storage.CachingConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + max_size_mbs: 0 + target_gc_percent: 0 + + +limits (`storage.LimitsConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets limits for stores. + +**Default Value**: + +.. code-block:: yaml + + maxDownloadMBs: 2 + + +defaultHttpClient (`storage.HTTPClientConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets the default http client config. + +**Default Value**: + +.. code-block:: yaml + + headers: null + timeout: 0s + + +signedUrl (`storage.SignedURLConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets config for SignedURL. + +**Default Value**: + +.. code-block:: yaml + + {} + + +storage.CachingConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +max_size_mbs (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum size of the cache where the Blob store data is cached in-memory. If not specified or set to 0, cache is not used + +**Default Value**: + +.. code-block:: yaml + + "0" + + +target_gc_percent (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets the garbage collection target percentage. + +**Default Value**: + +.. code-block:: yaml + + "0" + + +storage.ConnectionConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +endpoint (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +URL for storage client to connect to. + +**Default Value**: + +.. code-block:: yaml + + "" + + +auth-type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Auth Type to use [iam,accesskey]. + +**Default Value**: + +.. code-block:: yaml + + iam + + +access-key (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Access key to use. Only required when authtype is set to accesskey. + +**Default Value**: + +.. code-block:: yaml + + "" + + +secret-key (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Secret to use when accesskey is set. + +**Default Value**: + +.. code-block:: yaml + + "" + + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Region to connect to. + +**Default Value**: + +.. code-block:: yaml + + us-east-1 + + +disable-ssl (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Disables SSL connection. Should only be used for development. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.URL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +URL (`url.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + ForceQuery: false + Fragment: "" + Host: "" + OmitHost: false + Opaque: "" + Path: "" + RawFragment: "" + RawPath: "" + RawQuery: "" + Scheme: "" + User: null + + +url.URL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Scheme (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Opaque (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +User (url.Userinfo) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +Host (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Path (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +RawPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +OmitHost (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +ForceQuery (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +RawQuery (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Fragment (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +RawFragment (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +storage.HTTPClientConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +headers (map[string][]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets time out on the http client. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +storage.LimitsConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +maxDownloadMBs (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum allowed download size (in MBs) per call. + +**Default Value**: + +.. code-block:: yaml + + "2" + + +storage.SignedURLConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +stowConfigOverride (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +storage.StowConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +kind (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Kind of Stow backend to use. Refer to github/flyteorg/stow + +**Default Value**: + +.. code-block:: yaml + + "" + + +config (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Configuration for stow backend. Refer to github/flyteorg/stow + +**Default Value**: + +.. code-block:: yaml + + {} + + diff --git a/docs/deployment/configuration/generated/flyteadmin_config.rst b/docs/deployment/configuration/generated/flyteadmin_config.rst new file mode 100644 index 0000000000..8970bf6e73 --- /dev/null +++ b/docs/deployment/configuration/generated/flyteadmin_config.rst @@ -0,0 +1,5254 @@ +.. _flyteadmin-config-specification: + +######################################### +Flyte Admin Configuration +######################################### + +- `admin <#section-admin>`_ + +- `auth <#section-auth>`_ + +- `cloudevents <#section-cloudevents>`_ + +- `cluster_resources <#section-cluster_resources>`_ + +- `clusterpools <#section-clusterpools>`_ + +- `clusters <#section-clusters>`_ + +- `database <#section-database>`_ + +- `domains <#section-domains>`_ + +- `externalevents <#section-externalevents>`_ + +- `flyteadmin <#section-flyteadmin>`_ + +- `logger <#section-logger>`_ + +- `namespace_mapping <#section-namespace_mapping>`_ + +- `notifications <#section-notifications>`_ + +- `plugins <#section-plugins>`_ + +- `propeller <#section-propeller>`_ + +- `qualityofservice <#section-qualityofservice>`_ + +- `queues <#section-queues>`_ + +- `registration <#section-registration>`_ + +- `remotedata <#section-remotedata>`_ + +- `scheduler <#section-scheduler>`_ + +- `secrets <#section-secrets>`_ + +- `server <#section-server>`_ + +- `storage <#section-storage>`_ + +- `task_resources <#section-task_resources>`_ + +- `task_type_whitelist <#section-task_type_whitelist>`_ + +Section: admin +======================================================================================================================== + +endpoint (`config.URL`_) +------------------------------------------------------------------------------------------------------------------------ + +For admin types, specify where the uri of the service is located. + +**Default Value**: + +.. code-block:: yaml + + "" + + +insecure (bool) +------------------------------------------------------------------------------------------------------------------------ + +Use insecure connection. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +insecureSkipVerify (bool) +------------------------------------------------------------------------------------------------------------------------ + +InsecureSkipVerify controls whether a client verifies the server's certificate chain and host name. Caution : shouldn't be use for production usecases' + +**Default Value**: + +.. code-block:: yaml + + "false" + + +caCertFilePath (string) +------------------------------------------------------------------------------------------------------------------------ + +Use specified certificate file to verify the admin server peer. + +**Default Value**: + +.. code-block:: yaml + + "" + + +maxBackoffDelay (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Max delay for grpc backoff + +**Default Value**: + +.. code-block:: yaml + + 8s + + +perRetryTimeout (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +gRPC per retry timeout + +**Default Value**: + +.. code-block:: yaml + + 15s + + +maxRetries (int) +------------------------------------------------------------------------------------------------------------------------ + +Max number of gRPC retries + +**Default Value**: + +.. code-block:: yaml + + "4" + + +authType (uint8) +------------------------------------------------------------------------------------------------------------------------ + +Type of OAuth2 flow used for communicating with admin.ClientSecret,Pkce,ExternalCommand are valid values + +**Default Value**: + +.. code-block:: yaml + + ClientSecret + + +tokenRefreshWindow (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Max duration between token refresh attempt and token expiry. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +useAuth (bool) +------------------------------------------------------------------------------------------------------------------------ + +Deprecated: Auth will be enabled/disabled based on admin's dynamically discovered information. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +clientId (string) +------------------------------------------------------------------------------------------------------------------------ + +Client ID + +**Default Value**: + +.. code-block:: yaml + + flytepropeller + + +clientSecretLocation (string) +------------------------------------------------------------------------------------------------------------------------ + +File containing the client secret + +**Default Value**: + +.. code-block:: yaml + + /etc/secrets/client_secret + + +clientSecretEnvVar (string) +------------------------------------------------------------------------------------------------------------------------ + +Environment variable containing the client secret + +**Default Value**: + +.. code-block:: yaml + + "" + + +scopes ([]string) +------------------------------------------------------------------------------------------------------------------------ + +List of scopes to request + +**Default Value**: + +.. code-block:: yaml + + [] + + +useAudienceFromAdmin (bool) +------------------------------------------------------------------------------------------------------------------------ + +Use Audience configured from admins public endpoint config. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +audience (string) +------------------------------------------------------------------------------------------------------------------------ + +Audience to use when initiating OAuth2 authorization requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +authorizationServerUrl (string) +------------------------------------------------------------------------------------------------------------------------ + +This is the URL to your IdP's authorization server. It'll default to Endpoint + +**Default Value**: + +.. code-block:: yaml + + "" + + +tokenUrl (string) +------------------------------------------------------------------------------------------------------------------------ + +OPTIONAL: Your IdP's token endpoint. It'll be discovered from flyte admin's OAuth Metadata endpoint if not provided. + +**Default Value**: + +.. code-block:: yaml + + "" + + +authorizationHeader (string) +------------------------------------------------------------------------------------------------------------------------ + +Custom metadata header to pass JWT + +**Default Value**: + +.. code-block:: yaml + + "" + + +pkceConfig (`pkce.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +Config for Pkce authentication flow. + +**Default Value**: + +.. code-block:: yaml + + refreshTime: 5m0s + timeout: 2m0s + + +deviceFlowConfig (`deviceflow.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +Config for Device authentication flow. + +**Default Value**: + +.. code-block:: yaml + + pollInterval: 5s + refreshTime: 5m0s + timeout: 10m0s + + +command ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Command for external authentication token generation + +**Default Value**: + +.. code-block:: yaml + + [] + + +proxyCommand ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Command for external proxy-authorization token generation + +**Default Value**: + +.. code-block:: yaml + + [] + + +defaultServiceConfig (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +httpProxyURL (`config.URL`_) +------------------------------------------------------------------------------------------------------------------------ + +OPTIONAL: HTTP Proxy to be used for OAuth requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.Duration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Duration (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 8s + + +config.URL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +URL (`url.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + ForceQuery: false + Fragment: "" + Host: "" + OmitHost: false + Opaque: "" + Path: "" + RawFragment: "" + RawPath: "" + RawQuery: "" + Scheme: "" + User: null + + +url.URL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Scheme (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Opaque (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +User (url.Userinfo) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +Host (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Path (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +RawPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +OmitHost (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +ForceQuery (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +RawQuery (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Fragment (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +RawFragment (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +deviceflow.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +refreshTime (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +grace period from the token expiry after which it would refresh the token. + +**Default Value**: + +.. code-block:: yaml + + 5m0s + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +amount of time the device flow should complete or else it will be cancelled. + +**Default Value**: + +.. code-block:: yaml + + 10m0s + + +pollInterval (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +amount of time the device flow would poll the token endpoint if auth server doesn't return a polling interval. Okta and google IDP do return an interval' + +**Default Value**: + +.. code-block:: yaml + + 5s + + +pkce.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Amount of time the browser session would be active for authentication from client app. + +**Default Value**: + +.. code-block:: yaml + + 2m0s + + +refreshTime (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +grace period from the token expiry after which it would refresh the token. + +**Default Value**: + +.. code-block:: yaml + + 5m0s + + +Section: auth +======================================================================================================================== + +httpAuthorizationHeader (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + flyte-authorization + + +grpcAuthorizationHeader (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + flyte-authorization + + +disableForHttp (bool) +------------------------------------------------------------------------------------------------------------------------ + +Disables auth enforcement on HTTP Endpoints. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +disableForGrpc (bool) +------------------------------------------------------------------------------------------------------------------------ + +Disables auth enforcement on Grpc Endpoints. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +authorizedUris ([]config.URL) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +httpProxyURL (`config.URL`_) +------------------------------------------------------------------------------------------------------------------------ + +OPTIONAL: HTTP Proxy to be used for OAuth requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +userAuth (`config.UserAuthConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Defines Auth options for users. + +**Default Value**: + +.. code-block:: yaml + + cookieBlockKeySecretName: cookie_block_key + cookieHashKeySecretName: cookie_hash_key + cookieSetting: + domain: "" + sameSitePolicy: DefaultMode + httpProxyURL: "" + openId: + baseUrl: "" + clientId: "" + clientSecretFile: "" + clientSecretName: oidc_client_secret + scopes: + - openid + - profile + redirectUrl: /console + + +appAuth (`config.OAuth2Options`_) +------------------------------------------------------------------------------------------------------------------------ + +Defines Auth options for apps. UserAuth must be enabled for AppAuth to work. + +**Default Value**: + +.. code-block:: yaml + + authServerType: Self + externalAuthServer: + allowedAudience: [] + baseUrl: "" + httpProxyURL: "" + metadataUrl: "" + retryAttempts: 5 + retryDelay: 1s + selfAuthServer: + accessTokenLifespan: 30m0s + authorizationCodeLifespan: 5m0s + claimSymmetricEncryptionKeySecretName: claim_symmetric_key + issuer: "" + oldTokenSigningRSAKeySecretName: token_rsa_key_old.pem + refreshTokenLifespan: 1h0m0s + staticClients: + flyte-cli: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flyte-cli + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytectl: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flytectl + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytepropeller: + audience: null + client_secret: JDJhJDA2JGQ2UFFuMlFBRlUzY0w1VjhNRGtldXVrNjN4dWJxVXhOeGp0ZlB3LkZjOU1nVjZ2cG15T0l5 + grant_types: + - refresh_token + - client_credentials + id: flytepropeller + public: false + redirect_uris: + - http://localhost:3846/callback + response_types: + - token + scopes: + - all + - offline + - access_token + tokenSigningRSAKeySecretName: token_rsa_key.pem + thirdPartyConfig: + flyteClient: + audience: "" + clientId: flytectl + redirectUri: http://localhost:53593/callback + scopes: + - all + - offline + + +config.OAuth2Options +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +authServerType (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + Self + + +selfAuthServer (`config.AuthorizationServer`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Authorization Server config to run as a service. Use this when using an IdP that does not offer a custom OAuth2 Authorization Server. + +**Default Value**: + +.. code-block:: yaml + + accessTokenLifespan: 30m0s + authorizationCodeLifespan: 5m0s + claimSymmetricEncryptionKeySecretName: claim_symmetric_key + issuer: "" + oldTokenSigningRSAKeySecretName: token_rsa_key_old.pem + refreshTokenLifespan: 1h0m0s + staticClients: + flyte-cli: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flyte-cli + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytectl: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flytectl + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytepropeller: + audience: null + client_secret: JDJhJDA2JGQ2UFFuMlFBRlUzY0w1VjhNRGtldXVrNjN4dWJxVXhOeGp0ZlB3LkZjOU1nVjZ2cG15T0l5 + grant_types: + - refresh_token + - client_credentials + id: flytepropeller + public: false + redirect_uris: + - http://localhost:3846/callback + response_types: + - token + scopes: + - all + - offline + - access_token + tokenSigningRSAKeySecretName: token_rsa_key.pem + + +externalAuthServer (`config.ExternalAuthorizationServer`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +External Authorization Server config. + +**Default Value**: + +.. code-block:: yaml + + allowedAudience: [] + baseUrl: "" + httpProxyURL: "" + metadataUrl: "" + retryAttempts: 5 + retryDelay: 1s + + +thirdPartyConfig (`config.ThirdPartyConfigOptions`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines settings to instruct flyte cli tools (and optionally others) on what config to use to setup their client. + +**Default Value**: + +.. code-block:: yaml + + flyteClient: + audience: "" + clientId: flytectl + redirectUri: http://localhost:53593/callback + scopes: + - all + - offline + + +config.AuthorizationServer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +issuer (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the issuer to use when issuing and validating tokens. The default value is https:/// + +**Default Value**: + +.. code-block:: yaml + + "" + + +accessTokenLifespan (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the lifespan of issued access tokens. + +**Default Value**: + +.. code-block:: yaml + + 30m0s + + +refreshTokenLifespan (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the lifespan of issued access tokens. + +**Default Value**: + +.. code-block:: yaml + + 1h0m0s + + +authorizationCodeLifespan (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the lifespan of issued access tokens. + +**Default Value**: + +.. code-block:: yaml + + 5m0s + + +claimSymmetricEncryptionKeySecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Secret name to use to encrypt claims in authcode token. + +**Default Value**: + +.. code-block:: yaml + + claim_symmetric_key + + +tokenSigningRSAKeySecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Secret name to use to retrieve RSA Signing Key. + +**Default Value**: + +.. code-block:: yaml + + token_rsa_key.pem + + +oldTokenSigningRSAKeySecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Secret name to use to retrieve Old RSA Signing Key. This can be useful during key rotation to continue to accept older tokens. + +**Default Value**: + +.. code-block:: yaml + + token_rsa_key_old.pem + + +staticClients (map[string]*fosite.DefaultClient) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + flyte-cli: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flyte-cli + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytectl: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flytectl + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytepropeller: + audience: null + client_secret: JDJhJDA2JGQ2UFFuMlFBRlUzY0w1VjhNRGtldXVrNjN4dWJxVXhOeGp0ZlB3LkZjOU1nVjZ2cG15T0l5 + grant_types: + - refresh_token + - client_credentials + id: flytepropeller + public: false + redirect_uris: + - http://localhost:3846/callback + response_types: + - token + scopes: + - all + - offline + - access_token + + +config.ExternalAuthorizationServer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +baseUrl (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +This should be the base url of the authorization server that you are trying to hit. With Okta for instance, it will look something like https://company.okta.com/oauth2/abcdef123456789/ + +**Default Value**: + +.. code-block:: yaml + + "" + + +allowedAudience ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Optional: A list of allowed audiences. If not provided, the audience is expected to be the public Uri of the service. + +**Default Value**: + +.. code-block:: yaml + + [] + + +metadataUrl (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Optional: If the server doesn't support /.well-known/oauth-authorization-server, you can set a custom metadata url here.' + +**Default Value**: + +.. code-block:: yaml + + "" + + +httpProxyURL (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: HTTP Proxy to be used for OAuth requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +retryAttempts (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Optional: The number of attempted retries on a transient failure to get the OAuth metadata + +**Default Value**: + +.. code-block:: yaml + + "5" + + +retryDelay (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Optional, Duration to wait between retries + +**Default Value**: + +.. code-block:: yaml + + 1s + + +config.ThirdPartyConfigOptions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +flyteClient (`config.FlyteClientConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + audience: "" + clientId: flytectl + redirectUri: http://localhost:53593/callback + scopes: + - all + - offline + + +config.FlyteClientConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +clientId (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +public identifier for the app which handles authorization for a Flyte deployment + +**Default Value**: + +.. code-block:: yaml + + flytectl + + +redirectUri (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +This is the callback uri registered with the app which handles authorization for a Flyte deployment + +**Default Value**: + +.. code-block:: yaml + + http://localhost:53593/callback + + +scopes ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Recommended scopes for the client to request. + +**Default Value**: + +.. code-block:: yaml + + - all + - offline + + +audience (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Audience to use when initiating OAuth2 authorization requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.UserAuthConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +redirectUrl (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + /console + + +openId (`config.OpenIDOptions`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OpenID Configuration for User Auth + +**Default Value**: + +.. code-block:: yaml + + baseUrl: "" + clientId: "" + clientSecretFile: "" + clientSecretName: oidc_client_secret + scopes: + - openid + - profile + + +httpProxyURL (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: HTTP Proxy to be used for OAuth requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +cookieHashKeySecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Secret name to use for cookie hash key. + +**Default Value**: + +.. code-block:: yaml + + cookie_hash_key + + +cookieBlockKeySecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Secret name to use for cookie block key. + +**Default Value**: + +.. code-block:: yaml + + cookie_block_key + + +cookieSetting (`config.CookieSettings`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +settings used by cookies created for user auth + +**Default Value**: + +.. code-block:: yaml + + domain: "" + sameSitePolicy: DefaultMode + + +config.CookieSettings +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +sameSitePolicy (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Allows you to declare if your cookie should be restricted to a first-party or same-site context.Wrapper around http.SameSite. + +**Default Value**: + +.. code-block:: yaml + + DefaultMode + + +domain (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Allows you to set the domain attribute on the auth cookies. + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.OpenIDOptions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +clientId (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +clientSecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + oidc_client_secret + + +clientSecretFile (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +baseUrl (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +scopes ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + - openid + - profile + + +Section: cloudevents +======================================================================================================================== + +enable (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + local + + +aws (`interfaces.AWSConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + region: "" + + +gcp (`interfaces.GCPConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + projectId: "" + + +kafka (`interfaces.KafkaConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + brokers: null + version: "" + + +eventsPublisher (`interfaces.EventsPublisherConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + eventTypes: null + topicName: "" + + +reconnectAttempts (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +reconnectDelaySeconds (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +interfaces.AWSConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +interfaces.EventsPublisherConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +topicName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +eventTypes ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +interfaces.GCPConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +projectId (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +interfaces.KafkaConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +version (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +brokers ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +Section: cluster_resources +======================================================================================================================== + +templatePath (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +templateData (map[string]interfaces.DataSource) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + {} + + +refreshInterval (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + 1m0s + + +customData (map[string]map[string]interfaces.DataSource) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + {} + + +standaloneDeployment (bool) +------------------------------------------------------------------------------------------------------------------------ + +Whether the cluster resource sync is running in a standalone deployment and should call flyteadmin service endpoints + +**Default Value**: + +.. code-block:: yaml + + "false" + + +Section: clusterpools +======================================================================================================================== + +clusterPoolAssignments (map[string]interfaces.ClusterPoolAssignment) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + {} + + +Section: clusters +======================================================================================================================== + +clusterConfigs ([]interfaces.ClusterConfig) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +labelClusterMap (map[string][]interfaces.ClusterEntity) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +defaultExecutionLabel (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: database +======================================================================================================================== + +host (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +port (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +dbname (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +username (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +password (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +passwordPath (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +options (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +debug (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +enableForeignKeyConstraintWhenMigrating (bool) +------------------------------------------------------------------------------------------------------------------------ + +Whether to enable gorm foreign keys when migrating the db + +**Default Value**: + +.. code-block:: yaml + + "false" + + +maxIdleConnections (int) +------------------------------------------------------------------------------------------------------------------------ + +maxIdleConnections sets the maximum number of connections in the idle connection pool. + +**Default Value**: + +.. code-block:: yaml + + "10" + + +maxOpenConnections (int) +------------------------------------------------------------------------------------------------------------------------ + +maxOpenConnections sets the maximum number of open connections to the database. + +**Default Value**: + +.. code-block:: yaml + + "100" + + +connMaxLifeTime (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +sets the maximum amount of time a connection may be reused + +**Default Value**: + +.. code-block:: yaml + + 1h0m0s + + +postgres (`database.PostgresConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + dbname: postgres + debug: false + host: postgres + options: sslmode=disable + password: "" + passwordPath: "" + port: 5432 + username: postgres + + +sqlite (`database.SQLiteConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + file: "" + + +database.PostgresConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +host (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The host name of the database server + +**Default Value**: + +.. code-block:: yaml + + postgres + + +port (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The port name of the database server + +**Default Value**: + +.. code-block:: yaml + + "5432" + + +dbname (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The database name + +**Default Value**: + +.. code-block:: yaml + + postgres + + +username (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The database user who is connecting to the server. + +**Default Value**: + +.. code-block:: yaml + + postgres + + +password (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The database password. + +**Default Value**: + +.. code-block:: yaml + + "" + + +passwordPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Points to the file containing the database password. + +**Default Value**: + +.. code-block:: yaml + + "" + + +options (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +See http://gorm.io/docs/connecting_to_the_database.html for available options passed, in addition to the above. + +**Default Value**: + +.. code-block:: yaml + + sslmode=disable + + +debug (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Whether or not to start the database connection with debug mode enabled. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +database.SQLiteConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +file (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The path to the file (existing or new) where the DB should be created / stored. If existing, then this will be re-used, else a new will be created + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: domains +======================================================================================================================== + +id (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + development + + +name (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + development + + +Section: externalevents +======================================================================================================================== + +enable (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + local + + +aws (`interfaces.AWSConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + region: "" + + +gcp (`interfaces.GCPConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + projectId: "" + + +eventsPublisher (`interfaces.EventsPublisherConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + eventTypes: null + topicName: "" + + +reconnectAttempts (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +reconnectDelaySeconds (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +Section: flyteadmin +======================================================================================================================== + +roleNameKey (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +metricsScope (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + 'flyte:' + + +metricsKeys ([]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + - project + - domain + - wf + - task + - phase + - tasktype + - runtime_type + - runtime_version + - app_name + + +profilerPort (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "10254" + + +metadataStoragePrefix ([]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + - metadata + - admin + + +eventVersion (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "2" + + +asyncEventsBufferSize (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "100" + + +maxParallelism (int32) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "25" + + +labels (map[string]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +annotations (map[string]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +interruptible (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +overwriteCache (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +assumableIamRole (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +k8sServiceAccount (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +outputLocationPrefix (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +useOffloadedWorkflowClosure (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +envs (map[string]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +Section: logger +======================================================================================================================== + +show-source (bool) +------------------------------------------------------------------------------------------------------------------------ + +Includes source code location in logs. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +mute (bool) +------------------------------------------------------------------------------------------------------------------------ + +Mutes all logs regardless of severity. Intended for benchmarks/tests only. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +level (int) +------------------------------------------------------------------------------------------------------------------------ + +Sets the minimum logging level. + +**Default Value**: + +.. code-block:: yaml + + "3" + + +formatter (`logger.FormatterConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets logging format. + +**Default Value**: + +.. code-block:: yaml + + type: json + + +logger.FormatterConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets logging format type. + +**Default Value**: + +.. code-block:: yaml + + json + + +Section: namespace_mapping +======================================================================================================================== + +mapping (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +template (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + '{{ project }}-{{ domain }}' + + +templateData (map[string]interfaces.DataSource) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +Section: notifications +======================================================================================================================== + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + local + + +region (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +aws (`interfaces.AWSConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + region: "" + + +gcp (`interfaces.GCPConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + projectId: "" + + +publisher (`interfaces.NotificationsPublisherConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + topicName: "" + + +processor (`interfaces.NotificationsProcessorConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + accountId: "" + queueName: "" + + +emailer (`interfaces.NotificationsEmailerConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + body: "" + emailServerConfig: + apiKeyEnvVar: "" + apiKeyFilePath: "" + serviceName: "" + sender: "" + subject: "" + + +reconnectAttempts (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +reconnectDelaySeconds (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +interfaces.NotificationsEmailerConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +emailServerConfig (`interfaces.EmailServerConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + apiKeyEnvVar: "" + apiKeyFilePath: "" + serviceName: "" + + +subject (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +sender (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +body (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +interfaces.EmailServerConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +serviceName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +apiKeyEnvVar (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +apiKeyFilePath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +interfaces.NotificationsProcessorConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +queueName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +accountId (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +interfaces.NotificationsPublisherConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +topicName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: plugins +======================================================================================================================== + +catalogcache (`catalog.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + reader: + maxItems: 10000 + maxRetries: 3 + workers: 10 + writer: + maxItems: 10000 + maxRetries: 3 + workers: 10 + + +k8s (`config.K8sPluginConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + co-pilot: + cpu: 500m + default-input-path: /var/flyte/inputs + default-output-path: /var/flyte/outputs + image: cr.flyte.org/flyteorg/flytecopilot:v0.0.15 + input-vol-name: flyte-inputs + memory: 128Mi + name: flyte-copilot- + output-vol-name: flyte-outputs + start-timeout: 1m40s + storage: "" + create-container-error-grace-period: 3m0s + default-annotations: + cluster-autoscaler.kubernetes.io/safe-to-evict: "false" + default-cpus: "1" + default-env-vars: null + default-env-vars-from-env: null + default-labels: null + default-memory: 1Gi + default-node-selector: null + default-pod-dns-config: null + default-pod-security-context: null + default-pod-template-name: "" + default-pod-template-resync: 30s + default-security-context: null + default-tolerations: null + delete-resource-on-finalize: false + enable-host-networking-pod: null + gpu-device-node-label: k8s.amazonaws.com/accelerator + gpu-partition-size-node-label: k8s.amazonaws.com/gpu-partition-size + gpu-resource-name: nvidia.com/gpu + gpu-unpartitioned-node-selector-requirement: null + gpu-unpartitioned-toleration: null + image-pull-backoff-grace-period: 3m0s + inject-finalizer: false + interruptible-node-selector: null + interruptible-node-selector-requirement: null + interruptible-tolerations: null + non-interruptible-node-selector-requirement: null + resource-tolerations: null + scheduler-name: "" + send-object-events: false + + +catalog.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +reader (`workqueue.Config`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Catalog reader workqueue config. Make sure the index cache must be big enough to accommodate the biggest array task allowed to run on the system. + +**Default Value**: + +.. code-block:: yaml + + maxItems: 10000 + maxRetries: 3 + workers: 10 + + +writer (`workqueue.Config`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Catalog writer workqueue config. Make sure the index cache must be big enough to accommodate the biggest array task allowed to run on the system. + +**Default Value**: + +.. code-block:: yaml + + maxItems: 10000 + maxRetries: 3 + workers: 10 + + +workqueue.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +workers (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Number of concurrent workers to start processing the queue. + +**Default Value**: + +.. code-block:: yaml + + "10" + + +maxRetries (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum number of retries per item. + +**Default Value**: + +.. code-block:: yaml + + "3" + + +maxItems (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum number of entries to keep in the index. + +**Default Value**: + +.. code-block:: yaml + + "10000" + + +config.K8sPluginConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +inject-finalizer (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Instructs the plugin to inject a finalizer on startTask and remove it on task termination. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +default-annotations (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + cluster-autoscaler.kubernetes.io/safe-to-evict: "false" + + +default-labels (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-env-vars (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-env-vars-from-env (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-cpus (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines a default value for cpu for containers if not specified. + +**Default Value**: + +.. code-block:: yaml + + "1" + + +default-memory (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines a default value for memory for containers if not specified. + +**Default Value**: + +.. code-block:: yaml + + 1Gi + + +default-tolerations ([]v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-node-selector (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-affinity (v1.Affinity) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +scheduler-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines scheduler name. + +**Default Value**: + +.. code-block:: yaml + + "" + + +interruptible-tolerations ([]v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +interruptible-node-selector (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +interruptible-node-selector-requirement (v1.NodeSelectorRequirement) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +non-interruptible-node-selector-requirement (v1.NodeSelectorRequirement) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +resource-tolerations (map[v1.ResourceName][]v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +co-pilot (`config.FlyteCoPilotConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Co-Pilot Configuration + +**Default Value**: + +.. code-block:: yaml + + cpu: 500m + default-input-path: /var/flyte/inputs + default-output-path: /var/flyte/outputs + image: cr.flyte.org/flyteorg/flytecopilot:v0.0.15 + input-vol-name: flyte-inputs + memory: 128Mi + name: flyte-copilot- + output-vol-name: flyte-outputs + start-timeout: 1m40s + storage: "" + + +delete-resource-on-finalize (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Instructs the system to delete the resource upon successful execution of a k8s pod rather than have the k8s garbage collector clean it up. This ensures that no resources are kept around (potentially consuming cluster resources). This, however, will cause k8s log links to expire as soon as the resource is finalized. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +create-container-error-grace-period (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 3m0s + + +image-pull-backoff-grace-period (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 3m0s + + +gpu-device-node-label (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + k8s.amazonaws.com/accelerator + + +gpu-partition-size-node-label (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + k8s.amazonaws.com/gpu-partition-size + + +gpu-unpartitioned-node-selector-requirement (v1.NodeSelectorRequirement) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +gpu-unpartitioned-toleration (v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +gpu-resource-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + nvidia.com/gpu + + +default-pod-security-context (v1.PodSecurityContext) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-security-context (v1.SecurityContext) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +enable-host-networking-pod (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + + + +default-pod-dns-config (v1.PodDNSConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-pod-template-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the PodTemplate to use as the base for all k8s pods created by FlytePropeller. + +**Default Value**: + +.. code-block:: yaml + + "" + + +default-pod-template-resync (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Frequency of resyncing default pod templates + +**Default Value**: + +.. code-block:: yaml + + 30s + + +send-object-events (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +If true, will send k8s object events in TaskExecutionEvent updates. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.FlyteCoPilotConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Flyte co-pilot sidecar container name prefix. (additional bits will be added after this) + +**Default Value**: + +.. code-block:: yaml + + flyte-copilot- + + +image (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Flyte co-pilot Docker Image FQN + +**Default Value**: + +.. code-block:: yaml + + cr.flyte.org/flyteorg/flytecopilot:v0.0.15 + + +default-input-path (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default path where the volume should be mounted + +**Default Value**: + +.. code-block:: yaml + + /var/flyte/inputs + + +default-output-path (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default path where the volume should be mounted + +**Default Value**: + +.. code-block:: yaml + + /var/flyte/outputs + + +input-vol-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the data volume that is created for storing inputs + +**Default Value**: + +.. code-block:: yaml + + flyte-inputs + + +output-vol-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the data volume that is created for storing outputs + +**Default Value**: + +.. code-block:: yaml + + flyte-outputs + + +start-timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 1m40s + + +cpu (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Used to set cpu for co-pilot containers + +**Default Value**: + +.. code-block:: yaml + + 500m + + +memory (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Used to set memory for co-pilot containers + +**Default Value**: + +.. code-block:: yaml + + 128Mi + + +storage (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default storage limit for individual inputs / outputs + +**Default Value**: + +.. code-block:: yaml + + "" + + +resource.Quantity +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +i (`resource.int64Amount`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + {} + + +d (`resource.infDecAmount`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + + + +s (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "1" + + +Format (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + DecimalSI + + +resource.infDecAmount +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Dec (inf.Dec) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +resource.int64Amount +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +value (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "1" + + +scale (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + +Section: propeller +======================================================================================================================== + +kube-config (string) +------------------------------------------------------------------------------------------------------------------------ + +Path to kubernetes client config file. + +**Default Value**: + +.. code-block:: yaml + + "" + + +master (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +workers (int) +------------------------------------------------------------------------------------------------------------------------ + +Number of threads to process workflows + +**Default Value**: + +.. code-block:: yaml + + "20" + + +workflow-reeval-duration (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Frequency of re-evaluating workflows + +**Default Value**: + +.. code-block:: yaml + + 10s + + +downstream-eval-duration (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Frequency of re-evaluating downstream tasks + +**Default Value**: + +.. code-block:: yaml + + 30s + + +limit-namespace (string) +------------------------------------------------------------------------------------------------------------------------ + +Namespaces to watch for this propeller + +**Default Value**: + +.. code-block:: yaml + + all + + +prof-port (`config.Port`_) +------------------------------------------------------------------------------------------------------------------------ + +Profiler port + +**Default Value**: + +.. code-block:: yaml + + 10254 + + +metadata-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +MetadataPrefix should be used if all the metadata for Flyte executions should be stored under a specific prefix in CloudStorage. If not specified, the data will be stored in the base container directly. + +**Default Value**: + +.. code-block:: yaml + + metadata/propeller + + +rawoutput-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +a fully qualified storage path of the form s3://flyte/abc/..., where all data sandboxes should be stored. + +**Default Value**: + +.. code-block:: yaml + + "" + + +queue (`config.CompositeQueueConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Workflow workqueue configuration, affects the way the work is consumed from the queue. + +**Default Value**: + +.. code-block:: yaml + + batch-size: -1 + batching-interval: 1s + queue: + base-delay: 0s + capacity: 10000 + max-delay: 1m0s + rate: 1000 + type: maxof + sub-queue: + base-delay: 0s + capacity: 10000 + max-delay: 0s + rate: 1000 + type: bucket + type: batch + + +metrics-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +An optional prefix for all published metrics. + +**Default Value**: + +.. code-block:: yaml + + flyte + + +metrics-keys ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Metrics labels applied to prometheus metrics emitted by the service. + +**Default Value**: + +.. code-block:: yaml + + - project + - domain + - wf + - task + + +enable-admin-launcher (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable remote Workflow launcher to Admin + +**Default Value**: + +.. code-block:: yaml + + "true" + + +max-workflow-retries (int) +------------------------------------------------------------------------------------------------------------------------ + +Maximum number of retries per workflow + +**Default Value**: + +.. code-block:: yaml + + "10" + + +max-ttl-hours (int) +------------------------------------------------------------------------------------------------------------------------ + +Maximum number of hours a completed workflow should be retained. Number between 1-23 hours + +**Default Value**: + +.. code-block:: yaml + + "23" + + +gc-interval (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Run periodic GC every 30 minutes + +**Default Value**: + +.. code-block:: yaml + + 30m0s + + +leader-election (`config.LeaderElectionConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Config for leader election. + +**Default Value**: + +.. code-block:: yaml + + enabled: false + lease-duration: 15s + lock-config-map: + Name: "" + Namespace: "" + renew-deadline: 10s + retry-period: 2s + + +publish-k8s-events (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable events publishing to K8s events API. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +max-output-size-bytes (int64) +------------------------------------------------------------------------------------------------------------------------ + +Maximum size of outputs per task + +**Default Value**: + +.. code-block:: yaml + + "10485760" + + +enable-grpc-latency-metrics (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable grpc latency metrics. Note Histograms metrics can be expensive on Prometheus servers. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +kube-client-config (`config.KubeClientConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Configuration to control the Kubernetes client + +**Default Value**: + +.. code-block:: yaml + + burst: 25 + qps: 100 + timeout: 30s + + +node-config (`config.NodeConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +config for a workflow node + +**Default Value**: + +.. code-block:: yaml + + default-deadlines: + node-active-deadline: 0s + node-execution-deadline: 0s + workflow-active-deadline: 0s + default-max-attempts: 1 + ignore-retry-cause: false + interruptible-failure-threshold: -1 + max-node-retries-system-failures: 3 + + +max-streak-length (int) +------------------------------------------------------------------------------------------------------------------------ + +Maximum number of consecutive rounds that one propeller worker can use for one workflow - >1 => turbo-mode is enabled. + +**Default Value**: + +.. code-block:: yaml + + "8" + + +event-config (`config.EventConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Configures execution event behavior. + +**Default Value**: + +.. code-block:: yaml + + fallback-to-output-reference: false + raw-output-policy: reference + + +include-shard-key-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Include the specified shard key label in the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +exclude-shard-key-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Exclude the specified shard key label from the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +include-project-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Include the specified project label in the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +exclude-project-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Exclude the specified project label from the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +include-domain-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Include the specified domain label in the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +exclude-domain-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Exclude the specified domain label from the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +cluster-id (string) +------------------------------------------------------------------------------------------------------------------------ + +Unique cluster id running this flytepropeller instance with which to annotate execution events + +**Default Value**: + +.. code-block:: yaml + + propeller + + +create-flyteworkflow-crd (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable creation of the FlyteWorkflow CRD on startup + +**Default Value**: + +.. code-block:: yaml + + "false" + + +array-node-event-version (int) +------------------------------------------------------------------------------------------------------------------------ + +ArrayNode eventing version. 0 => legacy (drop-in replacement for maptask), 1 => new + +**Default Value**: + +.. code-block:: yaml + + "0" + + +config.CompositeQueueConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Type of composite queue to use for the WorkQueue + +**Default Value**: + +.. code-block:: yaml + + batch + + +queue (`config.WorkqueueConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Workflow workqueue configuration, affects the way the work is consumed from the queue. + +**Default Value**: + +.. code-block:: yaml + + base-delay: 0s + capacity: 10000 + max-delay: 1m0s + rate: 1000 + type: maxof + + +sub-queue (`config.WorkqueueConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +SubQueue configuration, affects the way the nodes cause the top-level Work to be re-evaluated. + +**Default Value**: + +.. code-block:: yaml + + base-delay: 0s + capacity: 10000 + max-delay: 0s + rate: 1000 + type: bucket + + +batching-interval (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration for which downstream updates are buffered + +**Default Value**: + +.. code-block:: yaml + + 1s + + +batch-size (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "-1" + + +config.WorkqueueConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Type of RateLimiter to use for the WorkQueue + +**Default Value**: + +.. code-block:: yaml + + maxof + + +base-delay (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +base backoff delay for failure + +**Default Value**: + +.. code-block:: yaml + + 0s + + +max-delay (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max backoff delay for failure + +**Default Value**: + +.. code-block:: yaml + + 1m0s + + +rate (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Bucket Refill rate per second + +**Default Value**: + +.. code-block:: yaml + + "1000" + + +capacity (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Bucket capacity as number of items + +**Default Value**: + +.. code-block:: yaml + + "10000" + + +config.EventConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +raw-output-policy (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +How output data should be passed along in execution events. + +**Default Value**: + +.. code-block:: yaml + + reference + + +fallback-to-output-reference (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Whether output data should be sent by reference when it is too large to be sent inline in execution events. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.KubeClientConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +qps (float32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "100" + + +burst (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max burst rate for throttle. 0 defaults to 10 + +**Default Value**: + +.. code-block:: yaml + + "25" + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max duration allowed for every request to KubeAPI before giving up. 0 implies no timeout. + +**Default Value**: + +.. code-block:: yaml + + 30s + + +config.LeaderElectionConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enables/Disables leader election. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +lock-config-map (`types.NamespacedName`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +ConfigMap namespace/name to use for resource lock. + +**Default Value**: + +.. code-block:: yaml + + Name: "" + Namespace: "" + + +lease-duration (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration that non-leader candidates will wait to force acquire leadership. This is measured against time of last observed ack. + +**Default Value**: + +.. code-block:: yaml + + 15s + + +renew-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration that the acting master will retry refreshing leadership before giving up. + +**Default Value**: + +.. code-block:: yaml + + 10s + + +retry-period (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration the LeaderElector clients should wait between tries of actions. + +**Default Value**: + +.. code-block:: yaml + + 2s + + +types.NamespacedName +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Namespace (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.NodeConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +default-deadlines (`config.DefaultDeadlines`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value for timeouts + +**Default Value**: + +.. code-block:: yaml + + node-active-deadline: 0s + node-execution-deadline: 0s + workflow-active-deadline: 0s + + +max-node-retries-system-failures (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum number of retries per node for node failure due to infra issues + +**Default Value**: + +.. code-block:: yaml + + "3" + + +interruptible-failure-threshold (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +number of failures for a node to be still considered interruptible. Negative numbers are treated as complementary (ex. -1 means last attempt is non-interruptible).' + +**Default Value**: + +.. code-block:: yaml + + "-1" + + +default-max-attempts (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default maximum number of attempts for a node + +**Default Value**: + +.. code-block:: yaml + + "1" + + +ignore-retry-cause (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Ignore retry cause and count all attempts toward a node's max attempts + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.DefaultDeadlines +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +node-execution-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value of node execution timeout that includes the time spent to run the node/workflow + +**Default Value**: + +.. code-block:: yaml + + 0s + + +node-active-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value of node timeout that includes the time spent queued. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +workflow-active-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value of workflow timeout that includes the time spent queued. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +config.Port +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +port (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "10254" + + +Section: qualityofservice +======================================================================================================================== + +tierExecutionValues (map[string]interfaces.QualityOfServiceSpec) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + {} + + +defaultTiers (map[string]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + {} + + +Section: queues +======================================================================================================================== + +executionQueues (interfaces.ExecutionQueues) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + [] + + +workflowConfigs (interfaces.WorkflowConfigs) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + [] + + +Section: registration +======================================================================================================================== + +maxWorkflowNodes (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "100" + + +maxLabelEntries (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +maxAnnotationEntries (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +workflowSizeLimit (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: remotedata +======================================================================================================================== + +scheme (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + none + + +region (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +signedUrls (`interfaces.SignedURL`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + durationMinutes: 0 + enabled: false + signingPrincipal: "" + + +maxSizeInBytes (int64) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "2097152" + + +inlineEventDataPolicy (int) +------------------------------------------------------------------------------------------------------------------------ + +Specifies how inline execution event data should be saved in the backend + +**Default Value**: + +.. code-block:: yaml + + Offload + + +interfaces.SignedURL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Whether signed urls should even be returned with GetExecutionData, GetNodeExecutionData and GetTaskExecutionData response objects. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +durationMinutes (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + +signingPrincipal (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: scheduler +======================================================================================================================== + +profilerPort (`config.Port`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + 10254 + + +eventScheduler (`interfaces.EventSchedulerConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + aws: null + local: {} + region: "" + scheduleNamePrefix: "" + scheduleRole: "" + scheme: local + targetName: "" + + +workflowExecutor (`interfaces.WorkflowExecutorConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + accountId: "" + aws: null + local: + adminRateLimit: + burst: 10 + tps: 100 + useUTCTz: false + region: "" + scheduleQueueName: "" + scheme: local + + +reconnectAttempts (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +reconnectDelaySeconds (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +interfaces.EventSchedulerConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +scheme (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + local + + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +scheduleRole (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +targetName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +scheduleNamePrefix (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +aws (interfaces.AWSSchedulerConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +local (`interfaces.FlyteSchedulerConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + {} + + +interfaces.FlyteSchedulerConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +interfaces.WorkflowExecutorConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +scheme (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + local + + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +scheduleQueueName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +accountId (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +aws (interfaces.AWSWorkflowExecutorConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +local (`interfaces.FlyteWorkflowExecutorConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + adminRateLimit: + burst: 10 + tps: 100 + useUTCTz: false + + +interfaces.FlyteWorkflowExecutorConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +adminRateLimit (`interfaces.AdminRateLimit`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + burst: 10 + tps: 100 + + +useUTCTz (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +interfaces.AdminRateLimit +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +tps (float64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "100" + + +burst (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "10" + + +Section: secrets +======================================================================================================================== + +secrets-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +Prefix where to look for secrets file + +**Default Value**: + +.. code-block:: yaml + + /etc/secrets + + +env-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +Prefix for environment variables + +**Default Value**: + +.. code-block:: yaml + + FLYTE_SECRET_ + + +Section: server +======================================================================================================================== + +httpPort (int) +------------------------------------------------------------------------------------------------------------------------ + +On which http port to serve admin + +**Default Value**: + +.. code-block:: yaml + + "8088" + + +grpcPort (int) +------------------------------------------------------------------------------------------------------------------------ + +deprecated + +**Default Value**: + +.. code-block:: yaml + + "0" + + +grpcServerReflection (bool) +------------------------------------------------------------------------------------------------------------------------ + +deprecated + +**Default Value**: + +.. code-block:: yaml + + "false" + + +kube-config (string) +------------------------------------------------------------------------------------------------------------------------ + +Path to kubernetes client config file, default is empty, useful for incluster config. + +**Default Value**: + +.. code-block:: yaml + + "" + + +master (string) +------------------------------------------------------------------------------------------------------------------------ + +The address of the Kubernetes API server. + +**Default Value**: + +.. code-block:: yaml + + "" + + +security (`config.ServerSecurityOptions`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + allowCors: true + allowedHeaders: + - Content-Type + - flyte-authorization + allowedOrigins: + - '*' + auditAccess: false + secure: false + ssl: + certificateFile: "" + keyFile: "" + useAuth: false + + +grpc (`config.GrpcConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + enableGrpcHistograms: false + maxMessageSizeBytes: 0 + port: 8089 + serverReflection: true + + +thirdPartyConfig (`config.ThirdPartyConfigOptions`_) +------------------------------------------------------------------------------------------------------------------------ + +Deprecated please use auth.appAuth.thirdPartyConfig instead. + +**Default Value**: + +.. code-block:: yaml + + flyteClient: + audience: "" + clientId: "" + redirectUri: "" + scopes: [] + + +dataProxy (`config.DataProxyConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Defines data proxy configuration. + +**Default Value**: + +.. code-block:: yaml + + download: + maxExpiresIn: 1h0m0s + upload: + defaultFileNameLength: 20 + maxExpiresIn: 1h0m0s + maxSize: 6Mi + storagePrefix: "" + + +readHeaderTimeoutSeconds (int) +------------------------------------------------------------------------------------------------------------------------ + +The amount of time allowed to read request headers. + +**Default Value**: + +.. code-block:: yaml + + "32" + + +kubeClientConfig (`config.KubeClientConfig (kubeClientConfig)`_) +------------------------------------------------------------------------------------------------------------------------ + +Configuration to control the Kubernetes client + +**Default Value**: + +.. code-block:: yaml + + burst: 25 + qps: 100 + timeout: 30s + + +config.DataProxyConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +upload (`config.DataProxyUploadConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines data proxy upload configuration. + +**Default Value**: + +.. code-block:: yaml + + defaultFileNameLength: 20 + maxExpiresIn: 1h0m0s + maxSize: 6Mi + storagePrefix: "" + + +download (`config.DataProxyDownloadConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines data proxy download configuration. + +**Default Value**: + +.. code-block:: yaml + + maxExpiresIn: 1h0m0s + + +config.DataProxyDownloadConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +maxExpiresIn (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum allowed expiration duration. + +**Default Value**: + +.. code-block:: yaml + + 1h0m0s + + +config.DataProxyUploadConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +maxSize (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum allowed upload size. + +**Default Value**: + +.. code-block:: yaml + + 6Mi + + +maxExpiresIn (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum allowed expiration duration. + +**Default Value**: + +.. code-block:: yaml + + 1h0m0s + + +defaultFileNameLength (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default length for the generated file name if not provided in the request. + +**Default Value**: + +.. code-block:: yaml + + "20" + + +storagePrefix (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Storage prefix to use for all upload requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.GrpcConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +port (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +On which grpc port to serve admin + +**Default Value**: + +.. code-block:: yaml + + "8089" + + +serverReflection (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable GRPC Server Reflection + +**Default Value**: + +.. code-block:: yaml + + "true" + + +maxMessageSizeBytes (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The max size in bytes for incoming gRPC messages + +**Default Value**: + +.. code-block:: yaml + + "0" + + +enableGrpcHistograms (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable grpc histograms + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.KubeClientConfig (kubeClientConfig) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +qps (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max QPS to the master for requests to KubeAPI. 0 defaults to 5. + +**Default Value**: + +.. code-block:: yaml + + "100" + + +burst (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max burst rate for throttle. 0 defaults to 10 + +**Default Value**: + +.. code-block:: yaml + + "25" + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max duration allowed for every request to KubeAPI before giving up. 0 implies no timeout. + +**Default Value**: + +.. code-block:: yaml + + 30s + + +config.ServerSecurityOptions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +secure (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +ssl (`config.SslOptions`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + certificateFile: "" + keyFile: "" + + +useAuth (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +auditAccess (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +allowCors (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "true" + + +allowedOrigins ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + - '*' + + +allowedHeaders ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + - Content-Type + - flyte-authorization + + +config.SslOptions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +certificateFile (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +keyFile (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: storage +======================================================================================================================== + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +Sets the type of storage to configure [s3/minio/local/mem/stow]. + +**Default Value**: + +.. code-block:: yaml + + s3 + + +connection (`storage.ConnectionConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + access-key: "" + auth-type: iam + disable-ssl: false + endpoint: "" + region: us-east-1 + secret-key: "" + + +stow (`storage.StowConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Storage config for stow backend. + +**Default Value**: + +.. code-block:: yaml + + {} + + +container (string) +------------------------------------------------------------------------------------------------------------------------ + +Initial container (in s3 a bucket) to create -if it doesn't exist-.' + +**Default Value**: + +.. code-block:: yaml + + "" + + +enable-multicontainer (bool) +------------------------------------------------------------------------------------------------------------------------ + +If this is true, then the container argument is overlooked and redundant. This config will automatically open new connections to new containers/buckets as they are encountered + +**Default Value**: + +.. code-block:: yaml + + "false" + + +cache (`storage.CachingConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + max_size_mbs: 0 + target_gc_percent: 0 + + +limits (`storage.LimitsConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets limits for stores. + +**Default Value**: + +.. code-block:: yaml + + maxDownloadMBs: 2 + + +defaultHttpClient (`storage.HTTPClientConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets the default http client config. + +**Default Value**: + +.. code-block:: yaml + + headers: null + timeout: 0s + + +signedUrl (`storage.SignedURLConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets config for SignedURL. + +**Default Value**: + +.. code-block:: yaml + + {} + + +storage.CachingConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +max_size_mbs (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum size of the cache where the Blob store data is cached in-memory. If not specified or set to 0, cache is not used + +**Default Value**: + +.. code-block:: yaml + + "0" + + +target_gc_percent (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets the garbage collection target percentage. + +**Default Value**: + +.. code-block:: yaml + + "0" + + +storage.ConnectionConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +endpoint (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +URL for storage client to connect to. + +**Default Value**: + +.. code-block:: yaml + + "" + + +auth-type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Auth Type to use [iam,accesskey]. + +**Default Value**: + +.. code-block:: yaml + + iam + + +access-key (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Access key to use. Only required when authtype is set to accesskey. + +**Default Value**: + +.. code-block:: yaml + + "" + + +secret-key (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Secret to use when accesskey is set. + +**Default Value**: + +.. code-block:: yaml + + "" + + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Region to connect to. + +**Default Value**: + +.. code-block:: yaml + + us-east-1 + + +disable-ssl (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Disables SSL connection. Should only be used for development. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +storage.HTTPClientConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +headers (map[string][]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets time out on the http client. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +storage.LimitsConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +maxDownloadMBs (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum allowed download size (in MBs) per call. + +**Default Value**: + +.. code-block:: yaml + + "2" + + +storage.SignedURLConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +stowConfigOverride (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +storage.StowConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +kind (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Kind of Stow backend to use. Refer to github/flyteorg/stow + +**Default Value**: + +.. code-block:: yaml + + "" + + +config (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Configuration for stow backend. Refer to github/flyteorg/stow + +**Default Value**: + +.. code-block:: yaml + + {} + + +Section: task_resources +======================================================================================================================== + +defaults (`interfaces.TaskResourceSet`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + cpu: "2" + ephemeralStorage: "0" + gpu: "0" + memory: 200Mi + storage: "0" + + +limits (`interfaces.TaskResourceSet`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + cpu: "2" + ephemeralStorage: "0" + gpu: "1" + memory: 1Gi + storage: "0" + + +interfaces.TaskResourceSet +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +cpu (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "2" + + +gpu (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + +memory (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 200Mi + + +storage (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + +ephemeralStorage (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + diff --git a/docs/deployment/configuration/generated/flytepropeller_config.rst b/docs/deployment/configuration/generated/flytepropeller_config.rst new file mode 100644 index 0000000000..3a85329ab3 --- /dev/null +++ b/docs/deployment/configuration/generated/flytepropeller_config.rst @@ -0,0 +1,5533 @@ +.. _flytepropeller-config-specification: + +######################################### +Flyte Propeller Configuration +######################################### + +- `admin <#section-admin>`_ + +- `catalog-cache <#section-catalog-cache>`_ + +- `event <#section-event>`_ + +- `logger <#section-logger>`_ + +- `plugins <#section-plugins>`_ + +- `propeller <#section-propeller>`_ + +- `secrets <#section-secrets>`_ + +- `storage <#section-storage>`_ + +- `tasks <#section-tasks>`_ + +- `webhook <#section-webhook>`_ + +Section: admin +======================================================================================================================== + +endpoint (`config.URL`_) +------------------------------------------------------------------------------------------------------------------------ + +For admin types, specify where the uri of the service is located. + +**Default Value**: + +.. code-block:: yaml + + "" + + +insecure (bool) +------------------------------------------------------------------------------------------------------------------------ + +Use insecure connection. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +insecureSkipVerify (bool) +------------------------------------------------------------------------------------------------------------------------ + +InsecureSkipVerify controls whether a client verifies the server's certificate chain and host name. Caution : shouldn't be use for production usecases' + +**Default Value**: + +.. code-block:: yaml + + "false" + + +caCertFilePath (string) +------------------------------------------------------------------------------------------------------------------------ + +Use specified certificate file to verify the admin server peer. + +**Default Value**: + +.. code-block:: yaml + + "" + + +maxBackoffDelay (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Max delay for grpc backoff + +**Default Value**: + +.. code-block:: yaml + + 8s + + +perRetryTimeout (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +gRPC per retry timeout + +**Default Value**: + +.. code-block:: yaml + + 15s + + +maxRetries (int) +------------------------------------------------------------------------------------------------------------------------ + +Max number of gRPC retries + +**Default Value**: + +.. code-block:: yaml + + "4" + + +authType (uint8) +------------------------------------------------------------------------------------------------------------------------ + +Type of OAuth2 flow used for communicating with admin.ClientSecret,Pkce,ExternalCommand are valid values + +**Default Value**: + +.. code-block:: yaml + + ClientSecret + + +tokenRefreshWindow (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Max duration between token refresh attempt and token expiry. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +useAuth (bool) +------------------------------------------------------------------------------------------------------------------------ + +Deprecated: Auth will be enabled/disabled based on admin's dynamically discovered information. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +clientId (string) +------------------------------------------------------------------------------------------------------------------------ + +Client ID + +**Default Value**: + +.. code-block:: yaml + + flytepropeller + + +clientSecretLocation (string) +------------------------------------------------------------------------------------------------------------------------ + +File containing the client secret + +**Default Value**: + +.. code-block:: yaml + + /etc/secrets/client_secret + + +clientSecretEnvVar (string) +------------------------------------------------------------------------------------------------------------------------ + +Environment variable containing the client secret + +**Default Value**: + +.. code-block:: yaml + + "" + + +scopes ([]string) +------------------------------------------------------------------------------------------------------------------------ + +List of scopes to request + +**Default Value**: + +.. code-block:: yaml + + [] + + +useAudienceFromAdmin (bool) +------------------------------------------------------------------------------------------------------------------------ + +Use Audience configured from admins public endpoint config. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +audience (string) +------------------------------------------------------------------------------------------------------------------------ + +Audience to use when initiating OAuth2 authorization requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +authorizationServerUrl (string) +------------------------------------------------------------------------------------------------------------------------ + +This is the URL to your IdP's authorization server. It'll default to Endpoint + +**Default Value**: + +.. code-block:: yaml + + "" + + +tokenUrl (string) +------------------------------------------------------------------------------------------------------------------------ + +OPTIONAL: Your IdP's token endpoint. It'll be discovered from flyte admin's OAuth Metadata endpoint if not provided. + +**Default Value**: + +.. code-block:: yaml + + "" + + +authorizationHeader (string) +------------------------------------------------------------------------------------------------------------------------ + +Custom metadata header to pass JWT + +**Default Value**: + +.. code-block:: yaml + + "" + + +pkceConfig (`pkce.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +Config for Pkce authentication flow. + +**Default Value**: + +.. code-block:: yaml + + refreshTime: 5m0s + timeout: 2m0s + + +deviceFlowConfig (`deviceflow.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +Config for Device authentication flow. + +**Default Value**: + +.. code-block:: yaml + + pollInterval: 5s + refreshTime: 5m0s + timeout: 10m0s + + +command ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Command for external authentication token generation + +**Default Value**: + +.. code-block:: yaml + + [] + + +proxyCommand ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Command for external proxy-authorization token generation + +**Default Value**: + +.. code-block:: yaml + + [] + + +defaultServiceConfig (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +httpProxyURL (`config.URL`_) +------------------------------------------------------------------------------------------------------------------------ + +OPTIONAL: HTTP Proxy to be used for OAuth requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.Duration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Duration (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 8s + + +config.URL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +URL (`url.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + ForceQuery: false + Fragment: "" + Host: "" + OmitHost: false + Opaque: "" + Path: "" + RawFragment: "" + RawPath: "" + RawQuery: "" + Scheme: "" + User: null + + +url.URL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Scheme (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Opaque (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +User (url.Userinfo) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +Host (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Path (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +RawPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +OmitHost (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +ForceQuery (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +RawQuery (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Fragment (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +RawFragment (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +deviceflow.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +refreshTime (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +grace period from the token expiry after which it would refresh the token. + +**Default Value**: + +.. code-block:: yaml + + 5m0s + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +amount of time the device flow should complete or else it will be cancelled. + +**Default Value**: + +.. code-block:: yaml + + 10m0s + + +pollInterval (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +amount of time the device flow would poll the token endpoint if auth server doesn't return a polling interval. Okta and google IDP do return an interval' + +**Default Value**: + +.. code-block:: yaml + + 5s + + +pkce.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Amount of time the browser session would be active for authentication from client app. + +**Default Value**: + +.. code-block:: yaml + + 2m0s + + +refreshTime (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +grace period from the token expiry after which it would refresh the token. + +**Default Value**: + +.. code-block:: yaml + + 5m0s + + +Section: catalog-cache +======================================================================================================================== + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +Catalog Implementation to use + +**Default Value**: + +.. code-block:: yaml + + noop + + +endpoint (string) +------------------------------------------------------------------------------------------------------------------------ + +Endpoint for catalog service + +**Default Value**: + +.. code-block:: yaml + + "" + + +insecure (bool) +------------------------------------------------------------------------------------------------------------------------ + +Use insecure grpc connection + +**Default Value**: + +.. code-block:: yaml + + "false" + + +max-cache-age (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Cache entries past this age will incur cache miss. 0 means cache never expires + +**Default Value**: + +.. code-block:: yaml + + 0s + + +use-admin-auth (bool) +------------------------------------------------------------------------------------------------------------------------ + +Use the same gRPC credentials option as the flyteadmin client + +**Default Value**: + +.. code-block:: yaml + + "false" + + +default-service-config (string) +------------------------------------------------------------------------------------------------------------------------ + +Set the default service config for the catalog gRPC client + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: event +======================================================================================================================== + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +Sets the type of EventSink to configure [log/admin/file]. + +**Default Value**: + +.. code-block:: yaml + + admin + + +file-path (string) +------------------------------------------------------------------------------------------------------------------------ + +For file types, specify where the file should be located. + +**Default Value**: + +.. code-block:: yaml + + "" + + +rate (int64) +------------------------------------------------------------------------------------------------------------------------ + +Max rate at which events can be recorded per second. + +**Default Value**: + +.. code-block:: yaml + + "500" + + +capacity (int) +------------------------------------------------------------------------------------------------------------------------ + +The max bucket size for event recording tokens. + +**Default Value**: + +.. code-block:: yaml + + "1000" + + +Section: logger +======================================================================================================================== + +show-source (bool) +------------------------------------------------------------------------------------------------------------------------ + +Includes source code location in logs. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +mute (bool) +------------------------------------------------------------------------------------------------------------------------ + +Mutes all logs regardless of severity. Intended for benchmarks/tests only. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +level (int) +------------------------------------------------------------------------------------------------------------------------ + +Sets the minimum logging level. + +**Default Value**: + +.. code-block:: yaml + + "3" + + +formatter (`logger.FormatterConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets logging format. + +**Default Value**: + +.. code-block:: yaml + + type: json + + +logger.FormatterConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets logging format type. + +**Default Value**: + +.. code-block:: yaml + + json + + +Section: plugins +======================================================================================================================== + +agent-service (`agent.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + agentForTaskTypes: null + agents: null + defaultAgent: + defaultServiceConfig: "" + defaultTimeout: 10s + endpoint: dns:///flyteagent.flyte.svc.cluster.local:80 + insecure: true + timeouts: null + resourceConstraints: + NamespaceScopeResourceConstraint: + Value: 50 + ProjectScopeResourceConstraint: + Value: 100 + supportedTaskTypes: + - task_type_1 + - task_type_2 + webApi: + caching: + maxSystemFailures: 5 + resyncInterval: 30s + size: 500000 + workers: 10 + readRateLimiter: + burst: 100 + qps: 10 + resourceMeta: null + resourceQuotas: + default: 1000 + writeRateLimiter: + burst: 100 + qps: 10 + + +athena (`athena.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + defaultCatalog: AwsDataCatalog + defaultWorkGroup: primary + resourceConstraints: + NamespaceScopeResourceConstraint: + Value: 50 + ProjectScopeResourceConstraint: + Value: 100 + webApi: + caching: + maxSystemFailures: 5 + resyncInterval: 30s + size: 500000 + workers: 10 + readRateLimiter: + burst: 100 + qps: 10 + resourceMeta: null + resourceQuotas: + default: 1000 + writeRateLimiter: + burst: 100 + qps: 10 + + +aws (`aws.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + accountId: "" + logLevel: 0 + region: us-east-2 + retries: 3 + + +bigquery (`bigquery.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + googleTokenSource: + gke-task-workload-identity: + remoteClusterConfig: + auth: + caCertPath: "" + tokenPath: "" + enabled: false + endpoint: "" + name: "" + type: default + resourceConstraints: + NamespaceScopeResourceConstraint: + Value: 50 + ProjectScopeResourceConstraint: + Value: 100 + webApi: + caching: + maxSystemFailures: 5 + resyncInterval: 30s + size: 500000 + workers: 10 + readRateLimiter: + burst: 100 + qps: 10 + resourceMeta: null + resourceQuotas: + default: 1000 + writeRateLimiter: + burst: 100 + qps: 10 + + +catalogcache (`catalog.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + reader: + maxItems: 10000 + maxRetries: 3 + workers: 10 + writer: + maxItems: 10000 + maxRetries: 3 + workers: 10 + + +databricks (`databricks.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + databricksInstance: "" + databricksTokenKey: FLYTE_DATABRICKS_API_TOKEN + defaultWarehouse: COMPUTE_CLUSTER + entrypointFile: "" + resourceConstraints: + NamespaceScopeResourceConstraint: + Value: 50 + ProjectScopeResourceConstraint: + Value: 100 + webApi: + caching: + maxSystemFailures: 5 + resyncInterval: 30s + size: 500000 + workers: 10 + readRateLimiter: + burst: 100 + qps: 10 + resourceMeta: null + resourceQuotas: + default: 1000 + writeRateLimiter: + burst: 100 + qps: 10 + + +k8s (`config.K8sPluginConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + co-pilot: + cpu: 500m + default-input-path: /var/flyte/inputs + default-output-path: /var/flyte/outputs + image: cr.flyte.org/flyteorg/flytecopilot:v0.0.15 + input-vol-name: flyte-inputs + memory: 128Mi + name: flyte-copilot- + output-vol-name: flyte-outputs + start-timeout: 1m40s + storage: "" + create-container-error-grace-period: 3m0s + default-annotations: + cluster-autoscaler.kubernetes.io/safe-to-evict: "false" + default-cpus: "1" + default-env-vars: null + default-env-vars-from-env: null + default-labels: null + default-memory: 1Gi + default-node-selector: null + default-pod-dns-config: null + default-pod-security-context: null + default-pod-template-name: "" + default-pod-template-resync: 30s + default-security-context: null + default-tolerations: null + delete-resource-on-finalize: false + enable-host-networking-pod: null + gpu-device-node-label: k8s.amazonaws.com/accelerator + gpu-partition-size-node-label: k8s.amazonaws.com/gpu-partition-size + gpu-resource-name: nvidia.com/gpu + gpu-unpartitioned-node-selector-requirement: null + gpu-unpartitioned-toleration: null + image-pull-backoff-grace-period: 3m0s + inject-finalizer: false + interruptible-node-selector: null + interruptible-node-selector-requirement: null + interruptible-tolerations: null + non-interruptible-node-selector-requirement: null + resource-tolerations: null + scheduler-name: "" + send-object-events: false + + +k8s-array (`k8s.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + ErrorAssembler: + maxItems: 100000 + maxRetries: 5 + workers: 10 + OutputAssembler: + maxItems: 100000 + maxRetries: 5 + workers: 10 + logs: + config: + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: true + kubernetes-template-uri: http://localhost:30082/#!/log/{{ .namespace }}/{{ .podName + }}/pod?namespace={{ .namespace }} + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + maxArrayJobSize: 5000 + maxErrorLength: 1000 + namespaceTemplate: "" + node-selector: null + remoteClusterConfig: + auth: + certPath: "" + tokenPath: "" + type: "" + enabled: false + endpoint: "" + name: "" + resourceConfig: + limit: 0 + primaryLabel: "" + scheduler: "" + tolerations: null + + +kf-operator (`common.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + timeout: 1m0s + + +logs (`logs.LogConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: true + kubernetes-template-uri: http://localhost:30082/#!/log/{{ .namespace }}/{{ .podName + }}/pod?namespace={{ .namespace }} + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + + +qubole (`config.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + analyzeLinkPath: /v2/analyze + clusterConfigs: + - labels: + - default + limit: 100 + namespaceScopeQuotaProportionCap: 0.7 + primaryLabel: default + projectScopeQuotaProportionCap: 0.7 + commandApiPath: /api/v1.2/commands/ + defaultClusterLabel: default + destinationClusterConfigs: [] + endpoint: https://wellness.qubole.com + lruCacheSize: 2000 + quboleTokenKey: FLYTE_QUBOLE_CLIENT_TOKEN + workers: 15 + + +ray (`ray.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + dashboardHost: 0.0.0.0 + defaults: + headNode: + ipAddress: $MY_POD_IP + startParameters: + disable-usage-stats: "true" + workerNode: + ipAddress: $MY_POD_IP + startParameters: + disable-usage-stats: "true" + enableUsageStats: false + includeDashboard: true + logs: + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: false + kubernetes-template-uri: "" + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + remoteClusterConfig: + auth: + caCertPath: "" + tokenPath: "" + enabled: false + endpoint: "" + name: "" + serviceType: NodePort + shutdownAfterJobFinishes: true + ttlSecondsAfterFinished: 3600 + + +sagemaker (`config.Config (sagemaker)`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + prebuiltAlgorithms: + - name: xgboost + regionalConfigs: + - region: us-east-1 + versionConfigs: + - image: 683313688378.dkr.ecr.us-east-1.amazonaws.com/sagemaker-xgboost:0.90-2-cpu-py3 + version: "0.90" + region: us-east-1 + roleAnnotationKey: "" + roleArn: default_role + + +snowflake (`snowflake.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + defaultWarehouse: COMPUTE_WH + resourceConstraints: + NamespaceScopeResourceConstraint: + Value: 50 + ProjectScopeResourceConstraint: + Value: 100 + snowflakeTokenKey: FLYTE_SNOWFLAKE_CLIENT_TOKEN + webApi: + caching: + maxSystemFailures: 5 + resyncInterval: 30s + size: 500000 + workers: 10 + readRateLimiter: + burst: 100 + qps: 10 + resourceMeta: null + resourceQuotas: + default: 1000 + writeRateLimiter: + burst: 100 + qps: 10 + + +spark (`spark.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + features: null + logs: + all-user: + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: false + kubernetes-template-uri: "" + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + mixed: + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: true + kubernetes-template-uri: http://localhost:30082/#!/log/{{ .namespace }}/{{ .podName + }}/pod?namespace={{ .namespace }} + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + system: + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: false + kubernetes-template-uri: "" + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + user: + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: false + kubernetes-template-uri: "" + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + spark-config-default: null + spark-history-server-url: "" + + +agent.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +webApi (`webapi.PluginConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines config for the base WebAPI plugin. + +**Default Value**: + +.. code-block:: yaml + + caching: + maxSystemFailures: 5 + resyncInterval: 30s + size: 500000 + workers: 10 + readRateLimiter: + burst: 100 + qps: 10 + resourceMeta: null + resourceQuotas: + default: 1000 + writeRateLimiter: + burst: 100 + qps: 10 + + +resourceConstraints (`core.ResourceConstraintsSpec`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + NamespaceScopeResourceConstraint: + Value: 50 + ProjectScopeResourceConstraint: + Value: 100 + + +defaultAgent (`agent.Agent`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The default agent. + +**Default Value**: + +.. code-block:: yaml + + defaultServiceConfig: "" + defaultTimeout: 10s + endpoint: dns:///flyteagent.flyte.svc.cluster.local:80 + insecure: true + timeouts: null + + +agents (map[string]*agent.Agent) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The agents. + +**Default Value**: + +.. code-block:: yaml + + null + + +agentForTaskTypes (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +supportedTaskTypes ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + - task_type_1 + - task_type_2 + + +agent.Agent +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +endpoint (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + dns:///flyteagent.flyte.svc.cluster.local:80 + + +insecure (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "true" + + +defaultServiceConfig (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +timeouts (map[string]config.Duration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +defaultTimeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 10s + + +core.ResourceConstraintsSpec +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ProjectScopeResourceConstraint (`core.ResourceConstraint`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + Value: 100 + + +NamespaceScopeResourceConstraint (`core.ResourceConstraint`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + Value: 50 + + +core.ResourceConstraint +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Value (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "100" + + +webapi.PluginConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +resourceQuotas (webapi.ResourceQuotas) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + default: 1000 + + +readRateLimiter (`webapi.RateLimiterConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines rate limiter properties for read actions (e.g. retrieve status). + +**Default Value**: + +.. code-block:: yaml + + burst: 100 + qps: 10 + + +writeRateLimiter (`webapi.RateLimiterConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines rate limiter properties for write actions. + +**Default Value**: + +.. code-block:: yaml + + burst: 100 + qps: 10 + + +caching (`webapi.CachingConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines caching characteristics. + +**Default Value**: + +.. code-block:: yaml + + maxSystemFailures: 5 + resyncInterval: 30s + size: 500000 + workers: 10 + + +resourceMeta (interface) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + + + +webapi.CachingConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +size (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the maximum number of items to cache. + +**Default Value**: + +.. code-block:: yaml + + "500000" + + +resyncInterval (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the sync interval. + +**Default Value**: + +.. code-block:: yaml + + 30s + + +workers (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the number of workers to start up to process items. + +**Default Value**: + +.. code-block:: yaml + + "10" + + +maxSystemFailures (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the number of failures to fetch a task before failing the task. + +**Default Value**: + +.. code-block:: yaml + + "5" + + +webapi.RateLimiterConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +qps (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the max rate of calls per second. + +**Default Value**: + +.. code-block:: yaml + + "10" + + +burst (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the maximum burst size. + +**Default Value**: + +.. code-block:: yaml + + "100" + + +athena.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +webApi (`webapi.PluginConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines config for the base WebAPI plugin. + +**Default Value**: + +.. code-block:: yaml + + caching: + maxSystemFailures: 5 + resyncInterval: 30s + size: 500000 + workers: 10 + readRateLimiter: + burst: 100 + qps: 10 + resourceMeta: null + resourceQuotas: + default: 1000 + writeRateLimiter: + burst: 100 + qps: 10 + + +resourceConstraints (`core.ResourceConstraintsSpec`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + NamespaceScopeResourceConstraint: + Value: 50 + ProjectScopeResourceConstraint: + Value: 100 + + +defaultWorkGroup (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the default workgroup to use when running on Athena unless overwritten by the task. + +**Default Value**: + +.. code-block:: yaml + + primary + + +defaultCatalog (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the default catalog to use when running on Athena unless overwritten by the task. + +**Default Value**: + +.. code-block:: yaml + + AwsDataCatalog + + +aws.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +AWS Region to connect to. + +**Default Value**: + +.. code-block:: yaml + + us-east-2 + + +accountId (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +AWS Account Identifier. + +**Default Value**: + +.. code-block:: yaml + + "" + + +retries (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Number of retries. + +**Default Value**: + +.. code-block:: yaml + + "3" + + +logLevel (uint64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + +bigquery.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +webApi (`webapi.PluginConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines config for the base WebAPI plugin. + +**Default Value**: + +.. code-block:: yaml + + caching: + maxSystemFailures: 5 + resyncInterval: 30s + size: 500000 + workers: 10 + readRateLimiter: + burst: 100 + qps: 10 + resourceMeta: null + resourceQuotas: + default: 1000 + writeRateLimiter: + burst: 100 + qps: 10 + + +resourceConstraints (`core.ResourceConstraintsSpec`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + NamespaceScopeResourceConstraint: + Value: 50 + ProjectScopeResourceConstraint: + Value: 100 + + +googleTokenSource (`google.TokenSourceFactoryConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines Google token source + +**Default Value**: + +.. code-block:: yaml + + gke-task-workload-identity: + remoteClusterConfig: + auth: + caCertPath: "" + tokenPath: "" + enabled: false + endpoint: "" + name: "" + type: default + + +bigQueryEndpoint (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +google.TokenSourceFactoryConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines type of TokenSourceFactory, possible values are 'default' and 'gke-task-workload-identity' + +**Default Value**: + +.. code-block:: yaml + + default + + +gke-task-workload-identity (`google.GkeTaskWorkloadIdentityTokenSourceFactoryConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Extra configuration for GKE task workload identity token source factory + +**Default Value**: + +.. code-block:: yaml + + remoteClusterConfig: + auth: + caCertPath: "" + tokenPath: "" + enabled: false + endpoint: "" + name: "" + + +google.GkeTaskWorkloadIdentityTokenSourceFactoryConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +remoteClusterConfig (`k8s.ClusterConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Configuration of remote GKE cluster + +**Default Value**: + +.. code-block:: yaml + + auth: + caCertPath: "" + tokenPath: "" + enabled: false + endpoint: "" + name: "" + + +k8s.ClusterConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Friendly name of the remote cluster + +**Default Value**: + +.. code-block:: yaml + + "" + + +endpoint (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Remote K8s cluster endpoint + +**Default Value**: + +.. code-block:: yaml + + "" + + +auth (`k8s.Auth`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + caCertPath: "" + tokenPath: "" + + +enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Boolean flag to enable or disable + +**Default Value**: + +.. code-block:: yaml + + "false" + + +k8s.Auth +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +tokenPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Token path + +**Default Value**: + +.. code-block:: yaml + + "" + + +caCertPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Certificate path + +**Default Value**: + +.. code-block:: yaml + + "" + + +catalog.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +reader (`workqueue.Config`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Catalog reader workqueue config. Make sure the index cache must be big enough to accommodate the biggest array task allowed to run on the system. + +**Default Value**: + +.. code-block:: yaml + + maxItems: 10000 + maxRetries: 3 + workers: 10 + + +writer (`workqueue.Config`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Catalog writer workqueue config. Make sure the index cache must be big enough to accommodate the biggest array task allowed to run on the system. + +**Default Value**: + +.. code-block:: yaml + + maxItems: 10000 + maxRetries: 3 + workers: 10 + + +workqueue.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +workers (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Number of concurrent workers to start processing the queue. + +**Default Value**: + +.. code-block:: yaml + + "10" + + +maxRetries (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum number of retries per item. + +**Default Value**: + +.. code-block:: yaml + + "3" + + +maxItems (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum number of entries to keep in the index. + +**Default Value**: + +.. code-block:: yaml + + "10000" + + +common.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 1m0s + + +config.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +endpoint (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Endpoint for qubole to use + +**Default Value**: + +.. code-block:: yaml + + https://wellness.qubole.com + + +commandApiPath (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +API Path where commands can be launched on Qubole. Should be a valid url. + +**Default Value**: + +.. code-block:: yaml + + /api/v1.2/commands/ + + +analyzeLinkPath (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +URL path where queries can be visualized on qubole website. Should be a valid url. + +**Default Value**: + +.. code-block:: yaml + + /v2/analyze + + +quboleTokenKey (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the key where to find Qubole token in the secret manager. + +**Default Value**: + +.. code-block:: yaml + + FLYTE_QUBOLE_CLIENT_TOKEN + + +lruCacheSize (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Size of the AutoRefreshCache + +**Default Value**: + +.. code-block:: yaml + + "2000" + + +workers (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Number of parallel workers to refresh the cache + +**Default Value**: + +.. code-block:: yaml + + "15" + + +defaultClusterLabel (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The default cluster label. This will be used if label is not specified on the hive job. + +**Default Value**: + +.. code-block:: yaml + + default + + +clusterConfigs ([]config.ClusterConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + - labels: + - default + limit: 100 + namespaceScopeQuotaProportionCap: 0.7 + primaryLabel: default + projectScopeQuotaProportionCap: 0.7 + + +destinationClusterConfigs ([]config.DestinationClusterConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + [] + + +config.Config (sagemaker) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +roleArn (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The role the SageMaker plugin uses to communicate with the SageMaker service + +**Default Value**: + +.. code-block:: yaml + + default_role + + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The AWS region the SageMaker plugin communicates to + +**Default Value**: + +.. code-block:: yaml + + us-east-1 + + +roleAnnotationKey (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Map key to use to lookup role from task annotations. + +**Default Value**: + +.. code-block:: yaml + + "" + + +prebuiltAlgorithms ([]config.PrebuiltAlgorithmConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + - name: xgboost + regionalConfigs: + - region: us-east-1 + versionConfigs: + - image: 683313688378.dkr.ecr.us-east-1.amazonaws.com/sagemaker-xgboost:0.90-2-cpu-py3 + version: "0.90" + + +config.K8sPluginConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +inject-finalizer (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Instructs the plugin to inject a finalizer on startTask and remove it on task termination. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +default-annotations (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + cluster-autoscaler.kubernetes.io/safe-to-evict: "false" + + +default-labels (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-env-vars (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-env-vars-from-env (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-cpus (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines a default value for cpu for containers if not specified. + +**Default Value**: + +.. code-block:: yaml + + "1" + + +default-memory (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines a default value for memory for containers if not specified. + +**Default Value**: + +.. code-block:: yaml + + 1Gi + + +default-tolerations ([]v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-node-selector (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-affinity (v1.Affinity) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +scheduler-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines scheduler name. + +**Default Value**: + +.. code-block:: yaml + + "" + + +interruptible-tolerations ([]v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +interruptible-node-selector (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +interruptible-node-selector-requirement (v1.NodeSelectorRequirement) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +non-interruptible-node-selector-requirement (v1.NodeSelectorRequirement) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +resource-tolerations (map[v1.ResourceName][]v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +co-pilot (`config.FlyteCoPilotConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Co-Pilot Configuration + +**Default Value**: + +.. code-block:: yaml + + cpu: 500m + default-input-path: /var/flyte/inputs + default-output-path: /var/flyte/outputs + image: cr.flyte.org/flyteorg/flytecopilot:v0.0.15 + input-vol-name: flyte-inputs + memory: 128Mi + name: flyte-copilot- + output-vol-name: flyte-outputs + start-timeout: 1m40s + storage: "" + + +delete-resource-on-finalize (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Instructs the system to delete the resource upon successful execution of a k8s pod rather than have the k8s garbage collector clean it up. This ensures that no resources are kept around (potentially consuming cluster resources). This, however, will cause k8s log links to expire as soon as the resource is finalized. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +create-container-error-grace-period (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 3m0s + + +image-pull-backoff-grace-period (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 3m0s + + +gpu-device-node-label (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + k8s.amazonaws.com/accelerator + + +gpu-partition-size-node-label (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + k8s.amazonaws.com/gpu-partition-size + + +gpu-unpartitioned-node-selector-requirement (v1.NodeSelectorRequirement) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +gpu-unpartitioned-toleration (v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +gpu-resource-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + nvidia.com/gpu + + +default-pod-security-context (v1.PodSecurityContext) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-security-context (v1.SecurityContext) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +enable-host-networking-pod (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + + + +default-pod-dns-config (v1.PodDNSConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-pod-template-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the PodTemplate to use as the base for all k8s pods created by FlytePropeller. + +**Default Value**: + +.. code-block:: yaml + + "" + + +default-pod-template-resync (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Frequency of resyncing default pod templates + +**Default Value**: + +.. code-block:: yaml + + 30s + + +send-object-events (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +If true, will send k8s object events in TaskExecutionEvent updates. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.FlyteCoPilotConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Flyte co-pilot sidecar container name prefix. (additional bits will be added after this) + +**Default Value**: + +.. code-block:: yaml + + flyte-copilot- + + +image (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Flyte co-pilot Docker Image FQN + +**Default Value**: + +.. code-block:: yaml + + cr.flyte.org/flyteorg/flytecopilot:v0.0.15 + + +default-input-path (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default path where the volume should be mounted + +**Default Value**: + +.. code-block:: yaml + + /var/flyte/inputs + + +default-output-path (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default path where the volume should be mounted + +**Default Value**: + +.. code-block:: yaml + + /var/flyte/outputs + + +input-vol-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the data volume that is created for storing inputs + +**Default Value**: + +.. code-block:: yaml + + flyte-inputs + + +output-vol-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the data volume that is created for storing outputs + +**Default Value**: + +.. code-block:: yaml + + flyte-outputs + + +start-timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 1m40s + + +cpu (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Used to set cpu for co-pilot containers + +**Default Value**: + +.. code-block:: yaml + + 500m + + +memory (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Used to set memory for co-pilot containers + +**Default Value**: + +.. code-block:: yaml + + 128Mi + + +storage (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default storage limit for individual inputs / outputs + +**Default Value**: + +.. code-block:: yaml + + "" + + +resource.Quantity +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +i (`resource.int64Amount`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + {} + + +d (`resource.infDecAmount`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + + + +s (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "1" + + +Format (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + DecimalSI + + +resource.infDecAmount +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Dec (inf.Dec) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +resource.int64Amount +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +value (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "1" + + +scale (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + +databricks.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +webApi (`webapi.PluginConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines config for the base WebAPI plugin. + +**Default Value**: + +.. code-block:: yaml + + caching: + maxSystemFailures: 5 + resyncInterval: 30s + size: 500000 + workers: 10 + readRateLimiter: + burst: 100 + qps: 10 + resourceMeta: null + resourceQuotas: + default: 1000 + writeRateLimiter: + burst: 100 + qps: 10 + + +resourceConstraints (`core.ResourceConstraintsSpec`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + NamespaceScopeResourceConstraint: + Value: 50 + ProjectScopeResourceConstraint: + Value: 100 + + +defaultWarehouse (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the default warehouse to use when running on Databricks unless overwritten by the task. + +**Default Value**: + +.. code-block:: yaml + + COMPUTE_CLUSTER + + +databricksTokenKey (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the key where to find Databricks token in the secret manager. + +**Default Value**: + +.. code-block:: yaml + + FLYTE_DATABRICKS_API_TOKEN + + +databricksInstance (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Databricks workspace instance name. + +**Default Value**: + +.. code-block:: yaml + + "" + + +entrypointFile (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +A URL of the entrypoint file. DBFS and cloud storage (s3://, gcs://, adls://, etc) locations are supported. + +**Default Value**: + +.. code-block:: yaml + + "" + + +databricksEndpoint (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +k8s.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +scheduler (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Decides the scheduler to use when launching array-pods. + +**Default Value**: + +.. code-block:: yaml + + "" + + +maxErrorLength (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Determines the maximum length of the error string returned for the array. + +**Default Value**: + +.. code-block:: yaml + + "1000" + + +maxArrayJobSize (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum size of array job. + +**Default Value**: + +.. code-block:: yaml + + "5000" + + +resourceConfig (`k8s.ResourceConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + limit: 0 + primaryLabel: "" + + +remoteClusterConfig (`k8s.ClusterConfig (remoteClusterConfig)`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + auth: + certPath: "" + tokenPath: "" + type: "" + enabled: false + endpoint: "" + name: "" + + +node-selector (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +tolerations ([]v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +namespaceTemplate (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +OutputAssembler (`workqueue.Config`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + maxItems: 100000 + maxRetries: 5 + workers: 10 + + +ErrorAssembler (`workqueue.Config`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + maxItems: 100000 + maxRetries: 5 + workers: 10 + + +logs (`k8s.LogConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Config for log links for k8s array jobs. + +**Default Value**: + +.. code-block:: yaml + + config: + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: true + kubernetes-template-uri: http://localhost:30082/#!/log/{{ .namespace }}/{{ .podName + }}/pod?namespace={{ .namespace }} + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + + +k8s.ClusterConfig (remoteClusterConfig) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Friendly name of the remote cluster + +**Default Value**: + +.. code-block:: yaml + + "" + + +endpoint (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Remote K8s cluster endpoint + +**Default Value**: + +.. code-block:: yaml + + "" + + +auth (`k8s.Auth (auth)`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + certPath: "" + tokenPath: "" + type: "" + + +enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Boolean flag to enable or disable + +**Default Value**: + +.. code-block:: yaml + + "false" + + +k8s.Auth (auth) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Authentication type + +**Default Value**: + +.. code-block:: yaml + + "" + + +tokenPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Token path + +**Default Value**: + +.. code-block:: yaml + + "" + + +certPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Certificate path + +**Default Value**: + +.. code-block:: yaml + + "" + + +k8s.LogConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +config (`logs.LogConfig (config)`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the log config for k8s logs. + +**Default Value**: + +.. code-block:: yaml + + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: true + kubernetes-template-uri: http://localhost:30082/#!/log/{{ .namespace }}/{{ .podName + }}/pod?namespace={{ .namespace }} + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + + +logs.LogConfig (config) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +cloudwatch-enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable Cloudwatch Logging + +**Default Value**: + +.. code-block:: yaml + + "false" + + +cloudwatch-region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +AWS region in which Cloudwatch logs are stored. + +**Default Value**: + +.. code-block:: yaml + + "" + + +cloudwatch-log-group (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Log group to which streams are associated. + +**Default Value**: + +.. code-block:: yaml + + "" + + +cloudwatch-template-uri (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Template Uri to use when building cloudwatch log links + +**Default Value**: + +.. code-block:: yaml + + "" + + +kubernetes-enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable Kubernetes Logging + +**Default Value**: + +.. code-block:: yaml + + "true" + + +kubernetes-url (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Console URL for Kubernetes logs + +**Default Value**: + +.. code-block:: yaml + + "" + + +kubernetes-template-uri (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Template Uri to use when building kubernetes log links + +**Default Value**: + +.. code-block:: yaml + + http://localhost:30082/#!/log/{{ .namespace }}/{{ .podName }}/pod?namespace={{ .namespace + }} + + +stackdriver-enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable Log-links to stackdriver + +**Default Value**: + +.. code-block:: yaml + + "false" + + +gcp-project (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the project in GCP + +**Default Value**: + +.. code-block:: yaml + + "" + + +stackdriver-logresourcename (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the logresource in stackdriver + +**Default Value**: + +.. code-block:: yaml + + "" + + +stackdriver-template-uri (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Template Uri to use when building stackdriver log links + +**Default Value**: + +.. code-block:: yaml + + "" + + +templates ([]logs.TemplateLogPluginConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +k8s.ResourceConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +primaryLabel (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +PrimaryLabel of a given service cluster + +**Default Value**: + +.. code-block:: yaml + + "" + + +limit (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Resource quota (in the number of outstanding requests) for the cluster + +**Default Value**: + +.. code-block:: yaml + + "0" + + +logs.LogConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +cloudwatch-enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable Cloudwatch Logging + +**Default Value**: + +.. code-block:: yaml + + "false" + + +cloudwatch-region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +AWS region in which Cloudwatch logs are stored. + +**Default Value**: + +.. code-block:: yaml + + "" + + +cloudwatch-log-group (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Log group to which streams are associated. + +**Default Value**: + +.. code-block:: yaml + + "" + + +cloudwatch-template-uri (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Template Uri to use when building cloudwatch log links + +**Default Value**: + +.. code-block:: yaml + + "" + + +kubernetes-enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable Kubernetes Logging + +**Default Value**: + +.. code-block:: yaml + + "true" + + +kubernetes-url (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Console URL for Kubernetes logs + +**Default Value**: + +.. code-block:: yaml + + "" + + +kubernetes-template-uri (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Template Uri to use when building kubernetes log links + +**Default Value**: + +.. code-block:: yaml + + http://localhost:30082/#!/log/{{ .namespace }}/{{ .podName }}/pod?namespace={{ .namespace + }} + + +stackdriver-enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable Log-links to stackdriver + +**Default Value**: + +.. code-block:: yaml + + "false" + + +gcp-project (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the project in GCP + +**Default Value**: + +.. code-block:: yaml + + "" + + +stackdriver-logresourcename (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the logresource in stackdriver + +**Default Value**: + +.. code-block:: yaml + + "" + + +stackdriver-template-uri (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Template Uri to use when building stackdriver log links + +**Default Value**: + +.. code-block:: yaml + + "" + + +templates ([]logs.TemplateLogPluginConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +ray.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +shutdownAfterJobFinishes (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "true" + + +ttlSecondsAfterFinished (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "3600" + + +serviceType (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + NodePort + + +includeDashboard (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "true" + + +dashboardHost (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 0.0.0.0 + + +nodeIPAddress (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +remoteClusterConfig (`k8s.ClusterConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Configuration of remote K8s cluster for ray jobs + +**Default Value**: + +.. code-block:: yaml + + auth: + caCertPath: "" + tokenPath: "" + enabled: false + endpoint: "" + name: "" + + +logs (`logs.LogConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: false + kubernetes-template-uri: "" + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + + +defaults (`ray.DefaultConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + headNode: + ipAddress: $MY_POD_IP + startParameters: + disable-usage-stats: "true" + workerNode: + ipAddress: $MY_POD_IP + startParameters: + disable-usage-stats: "true" + + +enableUsageStats (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable usage stats for ray jobs. These stats are submitted to usage-stats.ray.io per https://docs.ray.io/en/latest/cluster/usage-stats.html + +**Default Value**: + +.. code-block:: yaml + + "false" + + +ray.DefaultConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +headNode (`ray.NodeConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + ipAddress: $MY_POD_IP + startParameters: + disable-usage-stats: "true" + + +workerNode (`ray.NodeConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + ipAddress: $MY_POD_IP + startParameters: + disable-usage-stats: "true" + + +ray.NodeConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +startParameters (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + disable-usage-stats: "true" + + +ipAddress (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + $MY_POD_IP + + +snowflake.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +webApi (`webapi.PluginConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines config for the base WebAPI plugin. + +**Default Value**: + +.. code-block:: yaml + + caching: + maxSystemFailures: 5 + resyncInterval: 30s + size: 500000 + workers: 10 + readRateLimiter: + burst: 100 + qps: 10 + resourceMeta: null + resourceQuotas: + default: 1000 + writeRateLimiter: + burst: 100 + qps: 10 + + +resourceConstraints (`core.ResourceConstraintsSpec`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + NamespaceScopeResourceConstraint: + Value: 50 + ProjectScopeResourceConstraint: + Value: 100 + + +defaultWarehouse (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the default warehouse to use when running on Snowflake unless overwritten by the task. + +**Default Value**: + +.. code-block:: yaml + + COMPUTE_WH + + +snowflakeTokenKey (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the key where to find Snowflake token in the secret manager. + +**Default Value**: + +.. code-block:: yaml + + FLYTE_SNOWFLAKE_CLIENT_TOKEN + + +snowflakeEndpoint (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +spark.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +spark-config-default (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +spark-history-server-url (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +URL for SparkHistory Server that each job will publish the execution history to. + +**Default Value**: + +.. code-block:: yaml + + "" + + +features ([]spark.Feature) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +logs (`spark.LogConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Config for log links for spark applications. + +**Default Value**: + +.. code-block:: yaml + + all-user: + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: false + kubernetes-template-uri: "" + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + mixed: + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: true + kubernetes-template-uri: http://localhost:30082/#!/log/{{ .namespace }}/{{ .podName + }}/pod?namespace={{ .namespace }} + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + system: + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: false + kubernetes-template-uri: "" + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + user: + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: false + kubernetes-template-uri: "" + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + + +spark.LogConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +mixed (`logs.LogConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the log config that's not split into user/system. + +**Default Value**: + +.. code-block:: yaml + + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: true + kubernetes-template-uri: http://localhost:30082/#!/log/{{ .namespace }}/{{ .podName + }}/pod?namespace={{ .namespace }} + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + + +user (`logs.LogConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the log config for user logs. + +**Default Value**: + +.. code-block:: yaml + + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: false + kubernetes-template-uri: "" + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + + +system (`logs.LogConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the log config for system logs. + +**Default Value**: + +.. code-block:: yaml + + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: false + kubernetes-template-uri: "" + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + + +all-user (`logs.LogConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +All user logs across driver and executors. + +**Default Value**: + +.. code-block:: yaml + + cloudwatch-enabled: false + cloudwatch-log-group: "" + cloudwatch-region: "" + cloudwatch-template-uri: "" + gcp-project: "" + kubernetes-enabled: false + kubernetes-template-uri: "" + kubernetes-url: "" + stackdriver-enabled: false + stackdriver-logresourcename: "" + stackdriver-template-uri: "" + templates: null + + +Section: propeller +======================================================================================================================== + +kube-config (string) +------------------------------------------------------------------------------------------------------------------------ + +Path to kubernetes client config file. + +**Default Value**: + +.. code-block:: yaml + + "" + + +master (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +workers (int) +------------------------------------------------------------------------------------------------------------------------ + +Number of threads to process workflows + +**Default Value**: + +.. code-block:: yaml + + "20" + + +workflow-reeval-duration (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Frequency of re-evaluating workflows + +**Default Value**: + +.. code-block:: yaml + + 10s + + +downstream-eval-duration (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Frequency of re-evaluating downstream tasks + +**Default Value**: + +.. code-block:: yaml + + 30s + + +limit-namespace (string) +------------------------------------------------------------------------------------------------------------------------ + +Namespaces to watch for this propeller + +**Default Value**: + +.. code-block:: yaml + + all + + +prof-port (`config.Port`_) +------------------------------------------------------------------------------------------------------------------------ + +Profiler port + +**Default Value**: + +.. code-block:: yaml + + 10254 + + +metadata-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +MetadataPrefix should be used if all the metadata for Flyte executions should be stored under a specific prefix in CloudStorage. If not specified, the data will be stored in the base container directly. + +**Default Value**: + +.. code-block:: yaml + + metadata/propeller + + +rawoutput-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +a fully qualified storage path of the form s3://flyte/abc/..., where all data sandboxes should be stored. + +**Default Value**: + +.. code-block:: yaml + + "" + + +queue (`config.CompositeQueueConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Workflow workqueue configuration, affects the way the work is consumed from the queue. + +**Default Value**: + +.. code-block:: yaml + + batch-size: -1 + batching-interval: 1s + queue: + base-delay: 0s + capacity: 10000 + max-delay: 1m0s + rate: 1000 + type: maxof + sub-queue: + base-delay: 0s + capacity: 10000 + max-delay: 0s + rate: 1000 + type: bucket + type: batch + + +metrics-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +An optional prefix for all published metrics. + +**Default Value**: + +.. code-block:: yaml + + flyte + + +metrics-keys ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Metrics labels applied to prometheus metrics emitted by the service. + +**Default Value**: + +.. code-block:: yaml + + - project + - domain + - wf + - task + + +enable-admin-launcher (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable remote Workflow launcher to Admin + +**Default Value**: + +.. code-block:: yaml + + "true" + + +max-workflow-retries (int) +------------------------------------------------------------------------------------------------------------------------ + +Maximum number of retries per workflow + +**Default Value**: + +.. code-block:: yaml + + "10" + + +max-ttl-hours (int) +------------------------------------------------------------------------------------------------------------------------ + +Maximum number of hours a completed workflow should be retained. Number between 1-23 hours + +**Default Value**: + +.. code-block:: yaml + + "23" + + +gc-interval (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Run periodic GC every 30 minutes + +**Default Value**: + +.. code-block:: yaml + + 30m0s + + +leader-election (`config.LeaderElectionConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Config for leader election. + +**Default Value**: + +.. code-block:: yaml + + enabled: false + lease-duration: 15s + lock-config-map: + Name: "" + Namespace: "" + renew-deadline: 10s + retry-period: 2s + + +publish-k8s-events (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable events publishing to K8s events API. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +max-output-size-bytes (int64) +------------------------------------------------------------------------------------------------------------------------ + +Maximum size of outputs per task + +**Default Value**: + +.. code-block:: yaml + + "10485760" + + +enable-grpc-latency-metrics (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable grpc latency metrics. Note Histograms metrics can be expensive on Prometheus servers. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +kube-client-config (`config.KubeClientConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Configuration to control the Kubernetes client + +**Default Value**: + +.. code-block:: yaml + + burst: 25 + qps: 100 + timeout: 30s + + +node-config (`config.NodeConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +config for a workflow node + +**Default Value**: + +.. code-block:: yaml + + default-deadlines: + node-active-deadline: 0s + node-execution-deadline: 0s + workflow-active-deadline: 0s + default-max-attempts: 1 + ignore-retry-cause: false + interruptible-failure-threshold: -1 + max-node-retries-system-failures: 3 + + +max-streak-length (int) +------------------------------------------------------------------------------------------------------------------------ + +Maximum number of consecutive rounds that one propeller worker can use for one workflow - >1 => turbo-mode is enabled. + +**Default Value**: + +.. code-block:: yaml + + "8" + + +event-config (`config.EventConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Configures execution event behavior. + +**Default Value**: + +.. code-block:: yaml + + fallback-to-output-reference: false + raw-output-policy: reference + + +include-shard-key-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Include the specified shard key label in the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +exclude-shard-key-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Exclude the specified shard key label from the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +include-project-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Include the specified project label in the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +exclude-project-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Exclude the specified project label from the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +include-domain-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Include the specified domain label in the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +exclude-domain-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Exclude the specified domain label from the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +cluster-id (string) +------------------------------------------------------------------------------------------------------------------------ + +Unique cluster id running this flytepropeller instance with which to annotate execution events + +**Default Value**: + +.. code-block:: yaml + + propeller + + +create-flyteworkflow-crd (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable creation of the FlyteWorkflow CRD on startup + +**Default Value**: + +.. code-block:: yaml + + "false" + + +array-node-event-version (int) +------------------------------------------------------------------------------------------------------------------------ + +ArrayNode eventing version. 0 => legacy (drop-in replacement for maptask), 1 => new + +**Default Value**: + +.. code-block:: yaml + + "0" + + +admin-launcher (`launchplan.AdminConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + burst: 10 + cacheSize: 10000 + tps: 100 + workers: 10 + + +resourcemanager (`config.Config (resourcemanager)`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + redis: + hostKey: "" + hostPath: "" + hostPaths: [] + maxRetries: 0 + primaryName: "" + resourceMaxQuota: 1000 + type: noop + + +workflowstore (`workflowstore.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + policy: ResourceVersionCache + + +config.CompositeQueueConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Type of composite queue to use for the WorkQueue + +**Default Value**: + +.. code-block:: yaml + + batch + + +queue (`config.WorkqueueConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Workflow workqueue configuration, affects the way the work is consumed from the queue. + +**Default Value**: + +.. code-block:: yaml + + base-delay: 0s + capacity: 10000 + max-delay: 1m0s + rate: 1000 + type: maxof + + +sub-queue (`config.WorkqueueConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +SubQueue configuration, affects the way the nodes cause the top-level Work to be re-evaluated. + +**Default Value**: + +.. code-block:: yaml + + base-delay: 0s + capacity: 10000 + max-delay: 0s + rate: 1000 + type: bucket + + +batching-interval (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration for which downstream updates are buffered + +**Default Value**: + +.. code-block:: yaml + + 1s + + +batch-size (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "-1" + + +config.WorkqueueConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Type of RateLimiter to use for the WorkQueue + +**Default Value**: + +.. code-block:: yaml + + maxof + + +base-delay (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +base backoff delay for failure + +**Default Value**: + +.. code-block:: yaml + + 0s + + +max-delay (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max backoff delay for failure + +**Default Value**: + +.. code-block:: yaml + + 1m0s + + +rate (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Bucket Refill rate per second + +**Default Value**: + +.. code-block:: yaml + + "1000" + + +capacity (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Bucket capacity as number of items + +**Default Value**: + +.. code-block:: yaml + + "10000" + + +config.Config (resourcemanager) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Which resource manager to use + +**Default Value**: + +.. code-block:: yaml + + noop + + +resourceMaxQuota (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Global limit for concurrent Qubole queries + +**Default Value**: + +.. code-block:: yaml + + "1000" + + +redis (`config.RedisConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Config for Redis resourcemanager. + +**Default Value**: + +.. code-block:: yaml + + hostKey: "" + hostPath: "" + hostPaths: [] + maxRetries: 0 + primaryName: "" + + +config.RedisConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +hostPaths ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Redis hosts locations. + +**Default Value**: + +.. code-block:: yaml + + [] + + +primaryName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Redis primary name, fill in only if you are connecting to a redis sentinel cluster. + +**Default Value**: + +.. code-block:: yaml + + "" + + +hostPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Redis host location + +**Default Value**: + +.. code-block:: yaml + + "" + + +hostKey (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Key for local Redis access + +**Default Value**: + +.. code-block:: yaml + + "" + + +maxRetries (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +See Redis client options for more info + +**Default Value**: + +.. code-block:: yaml + + "0" + + +config.EventConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +raw-output-policy (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +How output data should be passed along in execution events. + +**Default Value**: + +.. code-block:: yaml + + reference + + +fallback-to-output-reference (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Whether output data should be sent by reference when it is too large to be sent inline in execution events. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.KubeClientConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +qps (float32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "100" + + +burst (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max burst rate for throttle. 0 defaults to 10 + +**Default Value**: + +.. code-block:: yaml + + "25" + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max duration allowed for every request to KubeAPI before giving up. 0 implies no timeout. + +**Default Value**: + +.. code-block:: yaml + + 30s + + +config.LeaderElectionConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enables/Disables leader election. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +lock-config-map (`types.NamespacedName`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +ConfigMap namespace/name to use for resource lock. + +**Default Value**: + +.. code-block:: yaml + + Name: "" + Namespace: "" + + +lease-duration (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration that non-leader candidates will wait to force acquire leadership. This is measured against time of last observed ack. + +**Default Value**: + +.. code-block:: yaml + + 15s + + +renew-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration that the acting master will retry refreshing leadership before giving up. + +**Default Value**: + +.. code-block:: yaml + + 10s + + +retry-period (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration the LeaderElector clients should wait between tries of actions. + +**Default Value**: + +.. code-block:: yaml + + 2s + + +types.NamespacedName +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Namespace (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.NodeConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +default-deadlines (`config.DefaultDeadlines`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value for timeouts + +**Default Value**: + +.. code-block:: yaml + + node-active-deadline: 0s + node-execution-deadline: 0s + workflow-active-deadline: 0s + + +max-node-retries-system-failures (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum number of retries per node for node failure due to infra issues + +**Default Value**: + +.. code-block:: yaml + + "3" + + +interruptible-failure-threshold (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +number of failures for a node to be still considered interruptible. Negative numbers are treated as complementary (ex. -1 means last attempt is non-interruptible).' + +**Default Value**: + +.. code-block:: yaml + + "-1" + + +default-max-attempts (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default maximum number of attempts for a node + +**Default Value**: + +.. code-block:: yaml + + "1" + + +ignore-retry-cause (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Ignore retry cause and count all attempts toward a node's max attempts + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.DefaultDeadlines +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +node-execution-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value of node execution timeout that includes the time spent to run the node/workflow + +**Default Value**: + +.. code-block:: yaml + + 0s + + +node-active-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value of node timeout that includes the time spent queued. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +workflow-active-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value of workflow timeout that includes the time spent queued. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +config.Port +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +port (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "10254" + + +launchplan.AdminConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +tps (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The maximum number of transactions per second to flyte admin from this client. + +**Default Value**: + +.. code-block:: yaml + + "100" + + +burst (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum burst for throttle + +**Default Value**: + +.. code-block:: yaml + + "10" + + +cacheSize (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum cache in terms of number of items stored. + +**Default Value**: + +.. code-block:: yaml + + "10000" + + +workers (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Number of parallel workers to work on the queue. + +**Default Value**: + +.. code-block:: yaml + + "10" + + +workflowstore.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +policy (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Workflow Store Policy to initialize + +**Default Value**: + +.. code-block:: yaml + + ResourceVersionCache + + +Section: secrets +======================================================================================================================== + +secrets-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +Prefix where to look for secrets file + +**Default Value**: + +.. code-block:: yaml + + /etc/secrets + + +env-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +Prefix for environment variables + +**Default Value**: + +.. code-block:: yaml + + FLYTE_SECRET_ + + +Section: storage +======================================================================================================================== + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +Sets the type of storage to configure [s3/minio/local/mem/stow]. + +**Default Value**: + +.. code-block:: yaml + + s3 + + +connection (`storage.ConnectionConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + access-key: "" + auth-type: iam + disable-ssl: false + endpoint: "" + region: us-east-1 + secret-key: "" + + +stow (`storage.StowConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Storage config for stow backend. + +**Default Value**: + +.. code-block:: yaml + + {} + + +container (string) +------------------------------------------------------------------------------------------------------------------------ + +Initial container (in s3 a bucket) to create -if it doesn't exist-.' + +**Default Value**: + +.. code-block:: yaml + + "" + + +enable-multicontainer (bool) +------------------------------------------------------------------------------------------------------------------------ + +If this is true, then the container argument is overlooked and redundant. This config will automatically open new connections to new containers/buckets as they are encountered + +**Default Value**: + +.. code-block:: yaml + + "false" + + +cache (`storage.CachingConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + max_size_mbs: 0 + target_gc_percent: 0 + + +limits (`storage.LimitsConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets limits for stores. + +**Default Value**: + +.. code-block:: yaml + + maxDownloadMBs: 2 + + +defaultHttpClient (`storage.HTTPClientConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets the default http client config. + +**Default Value**: + +.. code-block:: yaml + + headers: null + timeout: 0s + + +signedUrl (`storage.SignedURLConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets config for SignedURL. + +**Default Value**: + +.. code-block:: yaml + + {} + + +storage.CachingConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +max_size_mbs (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum size of the cache where the Blob store data is cached in-memory. If not specified or set to 0, cache is not used + +**Default Value**: + +.. code-block:: yaml + + "0" + + +target_gc_percent (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets the garbage collection target percentage. + +**Default Value**: + +.. code-block:: yaml + + "0" + + +storage.ConnectionConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +endpoint (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +URL for storage client to connect to. + +**Default Value**: + +.. code-block:: yaml + + "" + + +auth-type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Auth Type to use [iam,accesskey]. + +**Default Value**: + +.. code-block:: yaml + + iam + + +access-key (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Access key to use. Only required when authtype is set to accesskey. + +**Default Value**: + +.. code-block:: yaml + + "" + + +secret-key (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Secret to use when accesskey is set. + +**Default Value**: + +.. code-block:: yaml + + "" + + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Region to connect to. + +**Default Value**: + +.. code-block:: yaml + + us-east-1 + + +disable-ssl (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Disables SSL connection. Should only be used for development. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +storage.HTTPClientConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +headers (map[string][]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets time out on the http client. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +storage.LimitsConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +maxDownloadMBs (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum allowed download size (in MBs) per call. + +**Default Value**: + +.. code-block:: yaml + + "2" + + +storage.SignedURLConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +stowConfigOverride (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +storage.StowConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +kind (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Kind of Stow backend to use. Refer to github/flyteorg/stow + +**Default Value**: + +.. code-block:: yaml + + "" + + +config (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Configuration for stow backend. Refer to github/flyteorg/stow + +**Default Value**: + +.. code-block:: yaml + + {} + + +Section: tasks +======================================================================================================================== + +task-plugins (`config.TaskPluginConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Task plugin configuration + +**Default Value**: + +.. code-block:: yaml + + default-for-task-types: {} + enabled-plugins: [] + + +max-plugin-phase-versions (int32) +------------------------------------------------------------------------------------------------------------------------ + +Maximum number of plugin phase versions allowed for one phase. + +**Default Value**: + +.. code-block:: yaml + + "100000" + + +backoff (`config.BackOffConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Config for Exponential BackOff implementation + +**Default Value**: + +.. code-block:: yaml + + base-second: 2 + max-duration: 20s + + +maxLogMessageLength (int) +------------------------------------------------------------------------------------------------------------------------ + +Deprecated!!! Max length of error message. + +**Default Value**: + +.. code-block:: yaml + + "0" + + +config.BackOffConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +base-second (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The number of seconds representing the base duration of the exponential backoff + +**Default Value**: + +.. code-block:: yaml + + "2" + + +max-duration (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The cap of the backoff duration + +**Default Value**: + +.. code-block:: yaml + + 20s + + +config.TaskPluginConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +enabled-plugins ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Plugins enabled currently + +**Default Value**: + +.. code-block:: yaml + + [] + + +default-for-task-types (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + {} + + +Section: webhook +======================================================================================================================== + +metrics-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +An optional prefix for all published metrics. + +**Default Value**: + +.. code-block:: yaml + + 'flyte:' + + +certDir (string) +------------------------------------------------------------------------------------------------------------------------ + +Certificate directory to use to write generated certs. Defaults to /etc/webhook/certs/ + +**Default Value**: + +.. code-block:: yaml + + /etc/webhook/certs + + +localCert (bool) +------------------------------------------------------------------------------------------------------------------------ + +write certs locally. Defaults to false + +**Default Value**: + +.. code-block:: yaml + + "false" + + +listenPort (int) +------------------------------------------------------------------------------------------------------------------------ + +The port to use to listen to webhook calls. Defaults to 9443 + +**Default Value**: + +.. code-block:: yaml + + "9443" + + +serviceName (string) +------------------------------------------------------------------------------------------------------------------------ + +The name of the webhook service. + +**Default Value**: + +.. code-block:: yaml + + flyte-pod-webhook + + +servicePort (int32) +------------------------------------------------------------------------------------------------------------------------ + +The port on the service that hosting webhook. + +**Default Value**: + +.. code-block:: yaml + + "443" + + +secretName (string) +------------------------------------------------------------------------------------------------------------------------ + +Secret name to write generated certs to. + +**Default Value**: + +.. code-block:: yaml + + flyte-pod-webhook + + +secretManagerType (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + K8s + + +awsSecretManager (`config.AWSSecretManagerConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +AWS Secret Manager config. + +**Default Value**: + +.. code-block:: yaml + + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 200m + memory: 500Mi + sidecarImage: docker.io/amazon/aws-secrets-manager-secret-sidecar:v0.1.4 + + +gcpSecretManager (`config.GCPSecretManagerConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +GCP Secret Manager config. + +**Default Value**: + +.. code-block:: yaml + + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 200m + memory: 500Mi + sidecarImage: gcr.io/google.com/cloudsdktool/cloud-sdk:alpine + + +vaultSecretManager (`config.VaultSecretManagerConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Vault Secret Manager config. + +**Default Value**: + +.. code-block:: yaml + + annotations: null + kvVersion: "2" + role: flyte + + +config.AWSSecretManagerConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +sidecarImage (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Specifies the sidecar docker image to use + +**Default Value**: + +.. code-block:: yaml + + docker.io/amazon/aws-secrets-manager-secret-sidecar:v0.1.4 + + +resources (`v1.ResourceRequirements`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 200m + memory: 500Mi + + +v1.ResourceRequirements +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +limits (v1.ResourceList) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + cpu: 200m + memory: 500Mi + + +requests (v1.ResourceList) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + cpu: 200m + memory: 500Mi + + +config.GCPSecretManagerConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +sidecarImage (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Specifies the sidecar docker image to use + +**Default Value**: + +.. code-block:: yaml + + gcr.io/google.com/cloudsdktool/cloud-sdk:alpine + + +resources (`v1.ResourceRequirements`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 200m + memory: 500Mi + + +config.VaultSecretManagerConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +role (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Specifies the vault role to use + +**Default Value**: + +.. code-block:: yaml + + flyte + + +kvVersion (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "2" + + +annotations (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + diff --git a/docs/deployment/configuration/generated/index.md b/docs/deployment/configuration/generated/index.md new file mode 100644 index 0000000000..d4b9e2b414 --- /dev/null +++ b/docs/deployment/configuration/generated/index.md @@ -0,0 +1,31 @@ +(deployment-configuration-generated)= + +# Configuration Reference + +This section documents the configuration settings for Flyte's backend services. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {ref}`Flyte Scheduler ` + - The Flyte workflow scheduler service. +* - {ref}`Data Catalog ` + - The Flyte Data Catalog service. +* - {ref}`Flyte Admin ` + - The Flyte control plane. +* - {ref}`FlytePropeller ` + - Execution engine configuration +``` + +```{toctree} +:maxdepth: 1 +:caption: Generated Configuration Documentation +:name: generatedconfigdoctoc +:hidden: + +datacatalog_config +flyteadmin_config +flytepropeller_config +scheduler_config +``` diff --git a/docs/deployment/configuration/generated/scheduler_config.rst b/docs/deployment/configuration/generated/scheduler_config.rst new file mode 100644 index 0000000000..c2ed67edd7 --- /dev/null +++ b/docs/deployment/configuration/generated/scheduler_config.rst @@ -0,0 +1,5254 @@ +.. _flytescheduler-config-specification: + +######################################### +Flyte Scheduler Configuration +######################################### + +- `admin <#section-admin>`_ + +- `auth <#section-auth>`_ + +- `cloudevents <#section-cloudevents>`_ + +- `cluster_resources <#section-cluster_resources>`_ + +- `clusterpools <#section-clusterpools>`_ + +- `clusters <#section-clusters>`_ + +- `database <#section-database>`_ + +- `domains <#section-domains>`_ + +- `externalevents <#section-externalevents>`_ + +- `flyteadmin <#section-flyteadmin>`_ + +- `logger <#section-logger>`_ + +- `namespace_mapping <#section-namespace_mapping>`_ + +- `notifications <#section-notifications>`_ + +- `plugins <#section-plugins>`_ + +- `propeller <#section-propeller>`_ + +- `qualityofservice <#section-qualityofservice>`_ + +- `queues <#section-queues>`_ + +- `registration <#section-registration>`_ + +- `remotedata <#section-remotedata>`_ + +- `scheduler <#section-scheduler>`_ + +- `secrets <#section-secrets>`_ + +- `server <#section-server>`_ + +- `storage <#section-storage>`_ + +- `task_resources <#section-task_resources>`_ + +- `task_type_whitelist <#section-task_type_whitelist>`_ + +Section: admin +======================================================================================================================== + +endpoint (`config.URL`_) +------------------------------------------------------------------------------------------------------------------------ + +For admin types, specify where the uri of the service is located. + +**Default Value**: + +.. code-block:: yaml + + "" + + +insecure (bool) +------------------------------------------------------------------------------------------------------------------------ + +Use insecure connection. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +insecureSkipVerify (bool) +------------------------------------------------------------------------------------------------------------------------ + +InsecureSkipVerify controls whether a client verifies the server's certificate chain and host name. Caution : shouldn't be use for production usecases' + +**Default Value**: + +.. code-block:: yaml + + "false" + + +caCertFilePath (string) +------------------------------------------------------------------------------------------------------------------------ + +Use specified certificate file to verify the admin server peer. + +**Default Value**: + +.. code-block:: yaml + + "" + + +maxBackoffDelay (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Max delay for grpc backoff + +**Default Value**: + +.. code-block:: yaml + + 8s + + +perRetryTimeout (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +gRPC per retry timeout + +**Default Value**: + +.. code-block:: yaml + + 15s + + +maxRetries (int) +------------------------------------------------------------------------------------------------------------------------ + +Max number of gRPC retries + +**Default Value**: + +.. code-block:: yaml + + "4" + + +authType (uint8) +------------------------------------------------------------------------------------------------------------------------ + +Type of OAuth2 flow used for communicating with admin.ClientSecret,Pkce,ExternalCommand are valid values + +**Default Value**: + +.. code-block:: yaml + + ClientSecret + + +tokenRefreshWindow (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Max duration between token refresh attempt and token expiry. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +useAuth (bool) +------------------------------------------------------------------------------------------------------------------------ + +Deprecated: Auth will be enabled/disabled based on admin's dynamically discovered information. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +clientId (string) +------------------------------------------------------------------------------------------------------------------------ + +Client ID + +**Default Value**: + +.. code-block:: yaml + + flytepropeller + + +clientSecretLocation (string) +------------------------------------------------------------------------------------------------------------------------ + +File containing the client secret + +**Default Value**: + +.. code-block:: yaml + + /etc/secrets/client_secret + + +clientSecretEnvVar (string) +------------------------------------------------------------------------------------------------------------------------ + +Environment variable containing the client secret + +**Default Value**: + +.. code-block:: yaml + + "" + + +scopes ([]string) +------------------------------------------------------------------------------------------------------------------------ + +List of scopes to request + +**Default Value**: + +.. code-block:: yaml + + [] + + +useAudienceFromAdmin (bool) +------------------------------------------------------------------------------------------------------------------------ + +Use Audience configured from admins public endpoint config. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +audience (string) +------------------------------------------------------------------------------------------------------------------------ + +Audience to use when initiating OAuth2 authorization requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +authorizationServerUrl (string) +------------------------------------------------------------------------------------------------------------------------ + +This is the URL to your IdP's authorization server. It'll default to Endpoint + +**Default Value**: + +.. code-block:: yaml + + "" + + +tokenUrl (string) +------------------------------------------------------------------------------------------------------------------------ + +OPTIONAL: Your IdP's token endpoint. It'll be discovered from flyte admin's OAuth Metadata endpoint if not provided. + +**Default Value**: + +.. code-block:: yaml + + "" + + +authorizationHeader (string) +------------------------------------------------------------------------------------------------------------------------ + +Custom metadata header to pass JWT + +**Default Value**: + +.. code-block:: yaml + + "" + + +pkceConfig (`pkce.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +Config for Pkce authentication flow. + +**Default Value**: + +.. code-block:: yaml + + refreshTime: 5m0s + timeout: 2m0s + + +deviceFlowConfig (`deviceflow.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +Config for Device authentication flow. + +**Default Value**: + +.. code-block:: yaml + + pollInterval: 5s + refreshTime: 5m0s + timeout: 10m0s + + +command ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Command for external authentication token generation + +**Default Value**: + +.. code-block:: yaml + + [] + + +proxyCommand ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Command for external proxy-authorization token generation + +**Default Value**: + +.. code-block:: yaml + + [] + + +defaultServiceConfig (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +httpProxyURL (`config.URL`_) +------------------------------------------------------------------------------------------------------------------------ + +OPTIONAL: HTTP Proxy to be used for OAuth requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.Duration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Duration (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 8s + + +config.URL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +URL (`url.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + ForceQuery: false + Fragment: "" + Host: "" + OmitHost: false + Opaque: "" + Path: "" + RawFragment: "" + RawPath: "" + RawQuery: "" + Scheme: "" + User: null + + +url.URL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Scheme (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Opaque (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +User (url.Userinfo) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +Host (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Path (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +RawPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +OmitHost (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +ForceQuery (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +RawQuery (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Fragment (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +RawFragment (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +deviceflow.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +refreshTime (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +grace period from the token expiry after which it would refresh the token. + +**Default Value**: + +.. code-block:: yaml + + 5m0s + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +amount of time the device flow should complete or else it will be cancelled. + +**Default Value**: + +.. code-block:: yaml + + 10m0s + + +pollInterval (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +amount of time the device flow would poll the token endpoint if auth server doesn't return a polling interval. Okta and google IDP do return an interval' + +**Default Value**: + +.. code-block:: yaml + + 5s + + +pkce.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Amount of time the browser session would be active for authentication from client app. + +**Default Value**: + +.. code-block:: yaml + + 2m0s + + +refreshTime (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +grace period from the token expiry after which it would refresh the token. + +**Default Value**: + +.. code-block:: yaml + + 5m0s + + +Section: auth +======================================================================================================================== + +httpAuthorizationHeader (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + flyte-authorization + + +grpcAuthorizationHeader (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + flyte-authorization + + +disableForHttp (bool) +------------------------------------------------------------------------------------------------------------------------ + +Disables auth enforcement on HTTP Endpoints. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +disableForGrpc (bool) +------------------------------------------------------------------------------------------------------------------------ + +Disables auth enforcement on Grpc Endpoints. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +authorizedUris ([]config.URL) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +httpProxyURL (`config.URL`_) +------------------------------------------------------------------------------------------------------------------------ + +OPTIONAL: HTTP Proxy to be used for OAuth requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +userAuth (`config.UserAuthConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Defines Auth options for users. + +**Default Value**: + +.. code-block:: yaml + + cookieBlockKeySecretName: cookie_block_key + cookieHashKeySecretName: cookie_hash_key + cookieSetting: + domain: "" + sameSitePolicy: DefaultMode + httpProxyURL: "" + openId: + baseUrl: "" + clientId: "" + clientSecretFile: "" + clientSecretName: oidc_client_secret + scopes: + - openid + - profile + redirectUrl: /console + + +appAuth (`config.OAuth2Options`_) +------------------------------------------------------------------------------------------------------------------------ + +Defines Auth options for apps. UserAuth must be enabled for AppAuth to work. + +**Default Value**: + +.. code-block:: yaml + + authServerType: Self + externalAuthServer: + allowedAudience: [] + baseUrl: "" + httpProxyURL: "" + metadataUrl: "" + retryAttempts: 5 + retryDelay: 1s + selfAuthServer: + accessTokenLifespan: 30m0s + authorizationCodeLifespan: 5m0s + claimSymmetricEncryptionKeySecretName: claim_symmetric_key + issuer: "" + oldTokenSigningRSAKeySecretName: token_rsa_key_old.pem + refreshTokenLifespan: 1h0m0s + staticClients: + flyte-cli: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flyte-cli + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytectl: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flytectl + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytepropeller: + audience: null + client_secret: JDJhJDA2JGQ2UFFuMlFBRlUzY0w1VjhNRGtldXVrNjN4dWJxVXhOeGp0ZlB3LkZjOU1nVjZ2cG15T0l5 + grant_types: + - refresh_token + - client_credentials + id: flytepropeller + public: false + redirect_uris: + - http://localhost:3846/callback + response_types: + - token + scopes: + - all + - offline + - access_token + tokenSigningRSAKeySecretName: token_rsa_key.pem + thirdPartyConfig: + flyteClient: + audience: "" + clientId: flytectl + redirectUri: http://localhost:53593/callback + scopes: + - all + - offline + + +config.OAuth2Options +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +authServerType (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + Self + + +selfAuthServer (`config.AuthorizationServer`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Authorization Server config to run as a service. Use this when using an IdP that does not offer a custom OAuth2 Authorization Server. + +**Default Value**: + +.. code-block:: yaml + + accessTokenLifespan: 30m0s + authorizationCodeLifespan: 5m0s + claimSymmetricEncryptionKeySecretName: claim_symmetric_key + issuer: "" + oldTokenSigningRSAKeySecretName: token_rsa_key_old.pem + refreshTokenLifespan: 1h0m0s + staticClients: + flyte-cli: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flyte-cli + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytectl: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flytectl + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytepropeller: + audience: null + client_secret: JDJhJDA2JGQ2UFFuMlFBRlUzY0w1VjhNRGtldXVrNjN4dWJxVXhOeGp0ZlB3LkZjOU1nVjZ2cG15T0l5 + grant_types: + - refresh_token + - client_credentials + id: flytepropeller + public: false + redirect_uris: + - http://localhost:3846/callback + response_types: + - token + scopes: + - all + - offline + - access_token + tokenSigningRSAKeySecretName: token_rsa_key.pem + + +externalAuthServer (`config.ExternalAuthorizationServer`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +External Authorization Server config. + +**Default Value**: + +.. code-block:: yaml + + allowedAudience: [] + baseUrl: "" + httpProxyURL: "" + metadataUrl: "" + retryAttempts: 5 + retryDelay: 1s + + +thirdPartyConfig (`config.ThirdPartyConfigOptions`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines settings to instruct flyte cli tools (and optionally others) on what config to use to setup their client. + +**Default Value**: + +.. code-block:: yaml + + flyteClient: + audience: "" + clientId: flytectl + redirectUri: http://localhost:53593/callback + scopes: + - all + - offline + + +config.AuthorizationServer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +issuer (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the issuer to use when issuing and validating tokens. The default value is https:/// + +**Default Value**: + +.. code-block:: yaml + + "" + + +accessTokenLifespan (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the lifespan of issued access tokens. + +**Default Value**: + +.. code-block:: yaml + + 30m0s + + +refreshTokenLifespan (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the lifespan of issued access tokens. + +**Default Value**: + +.. code-block:: yaml + + 1h0m0s + + +authorizationCodeLifespan (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines the lifespan of issued access tokens. + +**Default Value**: + +.. code-block:: yaml + + 5m0s + + +claimSymmetricEncryptionKeySecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Secret name to use to encrypt claims in authcode token. + +**Default Value**: + +.. code-block:: yaml + + claim_symmetric_key + + +tokenSigningRSAKeySecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Secret name to use to retrieve RSA Signing Key. + +**Default Value**: + +.. code-block:: yaml + + token_rsa_key.pem + + +oldTokenSigningRSAKeySecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Secret name to use to retrieve Old RSA Signing Key. This can be useful during key rotation to continue to accept older tokens. + +**Default Value**: + +.. code-block:: yaml + + token_rsa_key_old.pem + + +staticClients (map[string]*fosite.DefaultClient) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + flyte-cli: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flyte-cli + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytectl: + audience: null + grant_types: + - refresh_token + - authorization_code + id: flytectl + public: true + redirect_uris: + - http://localhost:53593/callback + - http://localhost:12345/callback + response_types: + - code + - token + scopes: + - all + - offline + - access_token + flytepropeller: + audience: null + client_secret: JDJhJDA2JGQ2UFFuMlFBRlUzY0w1VjhNRGtldXVrNjN4dWJxVXhOeGp0ZlB3LkZjOU1nVjZ2cG15T0l5 + grant_types: + - refresh_token + - client_credentials + id: flytepropeller + public: false + redirect_uris: + - http://localhost:3846/callback + response_types: + - token + scopes: + - all + - offline + - access_token + + +config.ExternalAuthorizationServer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +baseUrl (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +This should be the base url of the authorization server that you are trying to hit. With Okta for instance, it will look something like https://company.okta.com/oauth2/abcdef123456789/ + +**Default Value**: + +.. code-block:: yaml + + "" + + +allowedAudience ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Optional: A list of allowed audiences. If not provided, the audience is expected to be the public Uri of the service. + +**Default Value**: + +.. code-block:: yaml + + [] + + +metadataUrl (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Optional: If the server doesn't support /.well-known/oauth-authorization-server, you can set a custom metadata url here.' + +**Default Value**: + +.. code-block:: yaml + + "" + + +httpProxyURL (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: HTTP Proxy to be used for OAuth requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +retryAttempts (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Optional: The number of attempted retries on a transient failure to get the OAuth metadata + +**Default Value**: + +.. code-block:: yaml + + "5" + + +retryDelay (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Optional, Duration to wait between retries + +**Default Value**: + +.. code-block:: yaml + + 1s + + +config.ThirdPartyConfigOptions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +flyteClient (`config.FlyteClientConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + audience: "" + clientId: flytectl + redirectUri: http://localhost:53593/callback + scopes: + - all + - offline + + +config.FlyteClientConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +clientId (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +public identifier for the app which handles authorization for a Flyte deployment + +**Default Value**: + +.. code-block:: yaml + + flytectl + + +redirectUri (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +This is the callback uri registered with the app which handles authorization for a Flyte deployment + +**Default Value**: + +.. code-block:: yaml + + http://localhost:53593/callback + + +scopes ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Recommended scopes for the client to request. + +**Default Value**: + +.. code-block:: yaml + + - all + - offline + + +audience (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Audience to use when initiating OAuth2 authorization requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.UserAuthConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +redirectUrl (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + /console + + +openId (`config.OpenIDOptions`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OpenID Configuration for User Auth + +**Default Value**: + +.. code-block:: yaml + + baseUrl: "" + clientId: "" + clientSecretFile: "" + clientSecretName: oidc_client_secret + scopes: + - openid + - profile + + +httpProxyURL (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: HTTP Proxy to be used for OAuth requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +cookieHashKeySecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Secret name to use for cookie hash key. + +**Default Value**: + +.. code-block:: yaml + + cookie_hash_key + + +cookieBlockKeySecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Secret name to use for cookie block key. + +**Default Value**: + +.. code-block:: yaml + + cookie_block_key + + +cookieSetting (`config.CookieSettings`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +settings used by cookies created for user auth + +**Default Value**: + +.. code-block:: yaml + + domain: "" + sameSitePolicy: DefaultMode + + +config.CookieSettings +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +sameSitePolicy (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Allows you to declare if your cookie should be restricted to a first-party or same-site context.Wrapper around http.SameSite. + +**Default Value**: + +.. code-block:: yaml + + DefaultMode + + +domain (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +OPTIONAL: Allows you to set the domain attribute on the auth cookies. + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.OpenIDOptions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +clientId (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +clientSecretName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + oidc_client_secret + + +clientSecretFile (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +baseUrl (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +scopes ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + - openid + - profile + + +Section: cloudevents +======================================================================================================================== + +enable (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + local + + +aws (`interfaces.AWSConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + region: "" + + +gcp (`interfaces.GCPConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + projectId: "" + + +kafka (`interfaces.KafkaConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + brokers: null + version: "" + + +eventsPublisher (`interfaces.EventsPublisherConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + eventTypes: null + topicName: "" + + +reconnectAttempts (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +reconnectDelaySeconds (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +interfaces.AWSConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +interfaces.EventsPublisherConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +topicName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +eventTypes ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +interfaces.GCPConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +projectId (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +interfaces.KafkaConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +version (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +brokers ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +Section: cluster_resources +======================================================================================================================== + +templatePath (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +templateData (map[string]interfaces.DataSource) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + {} + + +refreshInterval (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + 1m0s + + +customData (map[string]map[string]interfaces.DataSource) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + {} + + +standaloneDeployment (bool) +------------------------------------------------------------------------------------------------------------------------ + +Whether the cluster resource sync is running in a standalone deployment and should call flyteadmin service endpoints + +**Default Value**: + +.. code-block:: yaml + + "false" + + +Section: clusterpools +======================================================================================================================== + +clusterPoolAssignments (map[string]interfaces.ClusterPoolAssignment) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + {} + + +Section: clusters +======================================================================================================================== + +clusterConfigs ([]interfaces.ClusterConfig) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +labelClusterMap (map[string][]interfaces.ClusterEntity) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +defaultExecutionLabel (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: database +======================================================================================================================== + +host (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +port (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +dbname (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +username (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +password (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +passwordPath (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +options (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +debug (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +enableForeignKeyConstraintWhenMigrating (bool) +------------------------------------------------------------------------------------------------------------------------ + +Whether to enable gorm foreign keys when migrating the db + +**Default Value**: + +.. code-block:: yaml + + "false" + + +maxIdleConnections (int) +------------------------------------------------------------------------------------------------------------------------ + +maxIdleConnections sets the maximum number of connections in the idle connection pool. + +**Default Value**: + +.. code-block:: yaml + + "10" + + +maxOpenConnections (int) +------------------------------------------------------------------------------------------------------------------------ + +maxOpenConnections sets the maximum number of open connections to the database. + +**Default Value**: + +.. code-block:: yaml + + "100" + + +connMaxLifeTime (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +sets the maximum amount of time a connection may be reused + +**Default Value**: + +.. code-block:: yaml + + 1h0m0s + + +postgres (`database.PostgresConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + dbname: postgres + debug: false + host: postgres + options: sslmode=disable + password: "" + passwordPath: "" + port: 5432 + username: postgres + + +sqlite (`database.SQLiteConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + file: "" + + +database.PostgresConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +host (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The host name of the database server + +**Default Value**: + +.. code-block:: yaml + + postgres + + +port (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The port name of the database server + +**Default Value**: + +.. code-block:: yaml + + "5432" + + +dbname (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The database name + +**Default Value**: + +.. code-block:: yaml + + postgres + + +username (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The database user who is connecting to the server. + +**Default Value**: + +.. code-block:: yaml + + postgres + + +password (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The database password. + +**Default Value**: + +.. code-block:: yaml + + "" + + +passwordPath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Points to the file containing the database password. + +**Default Value**: + +.. code-block:: yaml + + "" + + +options (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +See http://gorm.io/docs/connecting_to_the_database.html for available options passed, in addition to the above. + +**Default Value**: + +.. code-block:: yaml + + sslmode=disable + + +debug (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Whether or not to start the database connection with debug mode enabled. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +database.SQLiteConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +file (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The path to the file (existing or new) where the DB should be created / stored. If existing, then this will be re-used, else a new will be created + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: domains +======================================================================================================================== + +id (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + development + + +name (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + development + + +Section: externalevents +======================================================================================================================== + +enable (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + local + + +aws (`interfaces.AWSConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + region: "" + + +gcp (`interfaces.GCPConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + projectId: "" + + +eventsPublisher (`interfaces.EventsPublisherConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + eventTypes: null + topicName: "" + + +reconnectAttempts (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +reconnectDelaySeconds (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +Section: flyteadmin +======================================================================================================================== + +roleNameKey (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +metricsScope (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + 'flyte:' + + +metricsKeys ([]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + - project + - domain + - wf + - task + - phase + - tasktype + - runtime_type + - runtime_version + - app_name + + +profilerPort (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "10254" + + +metadataStoragePrefix ([]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + - metadata + - admin + + +eventVersion (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "2" + + +asyncEventsBufferSize (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "100" + + +maxParallelism (int32) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "25" + + +labels (map[string]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +annotations (map[string]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +interruptible (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +overwriteCache (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +assumableIamRole (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +k8sServiceAccount (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +outputLocationPrefix (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +useOffloadedWorkflowClosure (bool) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "false" + + +envs (map[string]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +Section: logger +======================================================================================================================== + +show-source (bool) +------------------------------------------------------------------------------------------------------------------------ + +Includes source code location in logs. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +mute (bool) +------------------------------------------------------------------------------------------------------------------------ + +Mutes all logs regardless of severity. Intended for benchmarks/tests only. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +level (int) +------------------------------------------------------------------------------------------------------------------------ + +Sets the minimum logging level. + +**Default Value**: + +.. code-block:: yaml + + "3" + + +formatter (`logger.FormatterConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets logging format. + +**Default Value**: + +.. code-block:: yaml + + type: json + + +logger.FormatterConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets logging format type. + +**Default Value**: + +.. code-block:: yaml + + json + + +Section: namespace_mapping +======================================================================================================================== + +mapping (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +template (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + '{{ project }}-{{ domain }}' + + +templateData (map[string]interfaces.DataSource) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + null + + +Section: notifications +======================================================================================================================== + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + local + + +region (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +aws (`interfaces.AWSConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + region: "" + + +gcp (`interfaces.GCPConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + projectId: "" + + +publisher (`interfaces.NotificationsPublisherConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + topicName: "" + + +processor (`interfaces.NotificationsProcessorConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + accountId: "" + queueName: "" + + +emailer (`interfaces.NotificationsEmailerConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + body: "" + emailServerConfig: + apiKeyEnvVar: "" + apiKeyFilePath: "" + serviceName: "" + sender: "" + subject: "" + + +reconnectAttempts (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +reconnectDelaySeconds (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +interfaces.NotificationsEmailerConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +emailServerConfig (`interfaces.EmailServerConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + apiKeyEnvVar: "" + apiKeyFilePath: "" + serviceName: "" + + +subject (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +sender (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +body (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +interfaces.EmailServerConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +serviceName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +apiKeyEnvVar (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +apiKeyFilePath (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +interfaces.NotificationsProcessorConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +queueName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +accountId (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +interfaces.NotificationsPublisherConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +topicName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: plugins +======================================================================================================================== + +catalogcache (`catalog.Config`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + reader: + maxItems: 10000 + maxRetries: 3 + workers: 10 + writer: + maxItems: 10000 + maxRetries: 3 + workers: 10 + + +k8s (`config.K8sPluginConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + co-pilot: + cpu: 500m + default-input-path: /var/flyte/inputs + default-output-path: /var/flyte/outputs + image: cr.flyte.org/flyteorg/flytecopilot:v0.0.15 + input-vol-name: flyte-inputs + memory: 128Mi + name: flyte-copilot- + output-vol-name: flyte-outputs + start-timeout: 1m40s + storage: "" + create-container-error-grace-period: 3m0s + default-annotations: + cluster-autoscaler.kubernetes.io/safe-to-evict: "false" + default-cpus: "1" + default-env-vars: null + default-env-vars-from-env: null + default-labels: null + default-memory: 1Gi + default-node-selector: null + default-pod-dns-config: null + default-pod-security-context: null + default-pod-template-name: "" + default-pod-template-resync: 30s + default-security-context: null + default-tolerations: null + delete-resource-on-finalize: false + enable-host-networking-pod: null + gpu-device-node-label: k8s.amazonaws.com/accelerator + gpu-partition-size-node-label: k8s.amazonaws.com/gpu-partition-size + gpu-resource-name: nvidia.com/gpu + gpu-unpartitioned-node-selector-requirement: null + gpu-unpartitioned-toleration: null + image-pull-backoff-grace-period: 3m0s + inject-finalizer: false + interruptible-node-selector: null + interruptible-node-selector-requirement: null + interruptible-tolerations: null + non-interruptible-node-selector-requirement: null + resource-tolerations: null + scheduler-name: "" + send-object-events: false + + +catalog.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +reader (`workqueue.Config`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Catalog reader workqueue config. Make sure the index cache must be big enough to accommodate the biggest array task allowed to run on the system. + +**Default Value**: + +.. code-block:: yaml + + maxItems: 10000 + maxRetries: 3 + workers: 10 + + +writer (`workqueue.Config`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Catalog writer workqueue config. Make sure the index cache must be big enough to accommodate the biggest array task allowed to run on the system. + +**Default Value**: + +.. code-block:: yaml + + maxItems: 10000 + maxRetries: 3 + workers: 10 + + +workqueue.Config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +workers (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Number of concurrent workers to start processing the queue. + +**Default Value**: + +.. code-block:: yaml + + "10" + + +maxRetries (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum number of retries per item. + +**Default Value**: + +.. code-block:: yaml + + "3" + + +maxItems (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum number of entries to keep in the index. + +**Default Value**: + +.. code-block:: yaml + + "10000" + + +config.K8sPluginConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +inject-finalizer (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Instructs the plugin to inject a finalizer on startTask and remove it on task termination. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +default-annotations (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + cluster-autoscaler.kubernetes.io/safe-to-evict: "false" + + +default-labels (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-env-vars (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-env-vars-from-env (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-cpus (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines a default value for cpu for containers if not specified. + +**Default Value**: + +.. code-block:: yaml + + "1" + + +default-memory (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines a default value for memory for containers if not specified. + +**Default Value**: + +.. code-block:: yaml + + 1Gi + + +default-tolerations ([]v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-node-selector (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-affinity (v1.Affinity) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +scheduler-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines scheduler name. + +**Default Value**: + +.. code-block:: yaml + + "" + + +interruptible-tolerations ([]v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +interruptible-node-selector (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +interruptible-node-selector-requirement (v1.NodeSelectorRequirement) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +non-interruptible-node-selector-requirement (v1.NodeSelectorRequirement) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +resource-tolerations (map[v1.ResourceName][]v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +co-pilot (`config.FlyteCoPilotConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Co-Pilot Configuration + +**Default Value**: + +.. code-block:: yaml + + cpu: 500m + default-input-path: /var/flyte/inputs + default-output-path: /var/flyte/outputs + image: cr.flyte.org/flyteorg/flytecopilot:v0.0.15 + input-vol-name: flyte-inputs + memory: 128Mi + name: flyte-copilot- + output-vol-name: flyte-outputs + start-timeout: 1m40s + storage: "" + + +delete-resource-on-finalize (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Instructs the system to delete the resource upon successful execution of a k8s pod rather than have the k8s garbage collector clean it up. This ensures that no resources are kept around (potentially consuming cluster resources). This, however, will cause k8s log links to expire as soon as the resource is finalized. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +create-container-error-grace-period (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 3m0s + + +image-pull-backoff-grace-period (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 3m0s + + +gpu-device-node-label (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + k8s.amazonaws.com/accelerator + + +gpu-partition-size-node-label (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + k8s.amazonaws.com/gpu-partition-size + + +gpu-unpartitioned-node-selector-requirement (v1.NodeSelectorRequirement) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +gpu-unpartitioned-toleration (v1.Toleration) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +gpu-resource-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + nvidia.com/gpu + + +default-pod-security-context (v1.PodSecurityContext) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-security-context (v1.SecurityContext) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +enable-host-networking-pod (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + + + +default-pod-dns-config (v1.PodDNSConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +default-pod-template-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the PodTemplate to use as the base for all k8s pods created by FlytePropeller. + +**Default Value**: + +.. code-block:: yaml + + "" + + +default-pod-template-resync (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Frequency of resyncing default pod templates + +**Default Value**: + +.. code-block:: yaml + + 30s + + +send-object-events (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +If true, will send k8s object events in TaskExecutionEvent updates. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.FlyteCoPilotConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Flyte co-pilot sidecar container name prefix. (additional bits will be added after this) + +**Default Value**: + +.. code-block:: yaml + + flyte-copilot- + + +image (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Flyte co-pilot Docker Image FQN + +**Default Value**: + +.. code-block:: yaml + + cr.flyte.org/flyteorg/flytecopilot:v0.0.15 + + +default-input-path (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default path where the volume should be mounted + +**Default Value**: + +.. code-block:: yaml + + /var/flyte/inputs + + +default-output-path (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default path where the volume should be mounted + +**Default Value**: + +.. code-block:: yaml + + /var/flyte/outputs + + +input-vol-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the data volume that is created for storing inputs + +**Default Value**: + +.. code-block:: yaml + + flyte-inputs + + +output-vol-name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Name of the data volume that is created for storing outputs + +**Default Value**: + +.. code-block:: yaml + + flyte-outputs + + +start-timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 1m40s + + +cpu (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Used to set cpu for co-pilot containers + +**Default Value**: + +.. code-block:: yaml + + 500m + + +memory (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Used to set memory for co-pilot containers + +**Default Value**: + +.. code-block:: yaml + + 128Mi + + +storage (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default storage limit for individual inputs / outputs + +**Default Value**: + +.. code-block:: yaml + + "" + + +resource.Quantity +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +i (`resource.int64Amount`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + {} + + +d (`resource.infDecAmount`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + + + +s (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "1" + + +Format (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + DecimalSI + + +resource.infDecAmount +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Dec (inf.Dec) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +resource.int64Amount +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +value (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "1" + + +scale (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + +Section: propeller +======================================================================================================================== + +kube-config (string) +------------------------------------------------------------------------------------------------------------------------ + +Path to kubernetes client config file. + +**Default Value**: + +.. code-block:: yaml + + "" + + +master (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +workers (int) +------------------------------------------------------------------------------------------------------------------------ + +Number of threads to process workflows + +**Default Value**: + +.. code-block:: yaml + + "20" + + +workflow-reeval-duration (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Frequency of re-evaluating workflows + +**Default Value**: + +.. code-block:: yaml + + 10s + + +downstream-eval-duration (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Frequency of re-evaluating downstream tasks + +**Default Value**: + +.. code-block:: yaml + + 30s + + +limit-namespace (string) +------------------------------------------------------------------------------------------------------------------------ + +Namespaces to watch for this propeller + +**Default Value**: + +.. code-block:: yaml + + all + + +prof-port (`config.Port`_) +------------------------------------------------------------------------------------------------------------------------ + +Profiler port + +**Default Value**: + +.. code-block:: yaml + + 10254 + + +metadata-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +MetadataPrefix should be used if all the metadata for Flyte executions should be stored under a specific prefix in CloudStorage. If not specified, the data will be stored in the base container directly. + +**Default Value**: + +.. code-block:: yaml + + metadata/propeller + + +rawoutput-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +a fully qualified storage path of the form s3://flyte/abc/..., where all data sandboxes should be stored. + +**Default Value**: + +.. code-block:: yaml + + "" + + +queue (`config.CompositeQueueConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Workflow workqueue configuration, affects the way the work is consumed from the queue. + +**Default Value**: + +.. code-block:: yaml + + batch-size: -1 + batching-interval: 1s + queue: + base-delay: 0s + capacity: 10000 + max-delay: 1m0s + rate: 1000 + type: maxof + sub-queue: + base-delay: 0s + capacity: 10000 + max-delay: 0s + rate: 1000 + type: bucket + type: batch + + +metrics-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +An optional prefix for all published metrics. + +**Default Value**: + +.. code-block:: yaml + + flyte + + +metrics-keys ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Metrics labels applied to prometheus metrics emitted by the service. + +**Default Value**: + +.. code-block:: yaml + + - project + - domain + - wf + - task + + +enable-admin-launcher (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable remote Workflow launcher to Admin + +**Default Value**: + +.. code-block:: yaml + + "true" + + +max-workflow-retries (int) +------------------------------------------------------------------------------------------------------------------------ + +Maximum number of retries per workflow + +**Default Value**: + +.. code-block:: yaml + + "10" + + +max-ttl-hours (int) +------------------------------------------------------------------------------------------------------------------------ + +Maximum number of hours a completed workflow should be retained. Number between 1-23 hours + +**Default Value**: + +.. code-block:: yaml + + "23" + + +gc-interval (`config.Duration`_) +------------------------------------------------------------------------------------------------------------------------ + +Run periodic GC every 30 minutes + +**Default Value**: + +.. code-block:: yaml + + 30m0s + + +leader-election (`config.LeaderElectionConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Config for leader election. + +**Default Value**: + +.. code-block:: yaml + + enabled: false + lease-duration: 15s + lock-config-map: + Name: "" + Namespace: "" + renew-deadline: 10s + retry-period: 2s + + +publish-k8s-events (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable events publishing to K8s events API. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +max-output-size-bytes (int64) +------------------------------------------------------------------------------------------------------------------------ + +Maximum size of outputs per task + +**Default Value**: + +.. code-block:: yaml + + "10485760" + + +enable-grpc-latency-metrics (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable grpc latency metrics. Note Histograms metrics can be expensive on Prometheus servers. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +kube-client-config (`config.KubeClientConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Configuration to control the Kubernetes client + +**Default Value**: + +.. code-block:: yaml + + burst: 25 + qps: 100 + timeout: 30s + + +node-config (`config.NodeConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +config for a workflow node + +**Default Value**: + +.. code-block:: yaml + + default-deadlines: + node-active-deadline: 0s + node-execution-deadline: 0s + workflow-active-deadline: 0s + default-max-attempts: 1 + ignore-retry-cause: false + interruptible-failure-threshold: -1 + max-node-retries-system-failures: 3 + + +max-streak-length (int) +------------------------------------------------------------------------------------------------------------------------ + +Maximum number of consecutive rounds that one propeller worker can use for one workflow - >1 => turbo-mode is enabled. + +**Default Value**: + +.. code-block:: yaml + + "8" + + +event-config (`config.EventConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Configures execution event behavior. + +**Default Value**: + +.. code-block:: yaml + + fallback-to-output-reference: false + raw-output-policy: reference + + +include-shard-key-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Include the specified shard key label in the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +exclude-shard-key-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Exclude the specified shard key label from the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +include-project-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Include the specified project label in the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +exclude-project-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Exclude the specified project label from the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +include-domain-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Include the specified domain label in the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +exclude-domain-label ([]string) +------------------------------------------------------------------------------------------------------------------------ + +Exclude the specified domain label from the k8s FlyteWorkflow CRD label selector + +**Default Value**: + +.. code-block:: yaml + + [] + + +cluster-id (string) +------------------------------------------------------------------------------------------------------------------------ + +Unique cluster id running this flytepropeller instance with which to annotate execution events + +**Default Value**: + +.. code-block:: yaml + + propeller + + +create-flyteworkflow-crd (bool) +------------------------------------------------------------------------------------------------------------------------ + +Enable creation of the FlyteWorkflow CRD on startup + +**Default Value**: + +.. code-block:: yaml + + "false" + + +array-node-event-version (int) +------------------------------------------------------------------------------------------------------------------------ + +ArrayNode eventing version. 0 => legacy (drop-in replacement for maptask), 1 => new + +**Default Value**: + +.. code-block:: yaml + + "0" + + +config.CompositeQueueConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Type of composite queue to use for the WorkQueue + +**Default Value**: + +.. code-block:: yaml + + batch + + +queue (`config.WorkqueueConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Workflow workqueue configuration, affects the way the work is consumed from the queue. + +**Default Value**: + +.. code-block:: yaml + + base-delay: 0s + capacity: 10000 + max-delay: 1m0s + rate: 1000 + type: maxof + + +sub-queue (`config.WorkqueueConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +SubQueue configuration, affects the way the nodes cause the top-level Work to be re-evaluated. + +**Default Value**: + +.. code-block:: yaml + + base-delay: 0s + capacity: 10000 + max-delay: 0s + rate: 1000 + type: bucket + + +batching-interval (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration for which downstream updates are buffered + +**Default Value**: + +.. code-block:: yaml + + 1s + + +batch-size (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "-1" + + +config.WorkqueueConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Type of RateLimiter to use for the WorkQueue + +**Default Value**: + +.. code-block:: yaml + + maxof + + +base-delay (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +base backoff delay for failure + +**Default Value**: + +.. code-block:: yaml + + 0s + + +max-delay (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max backoff delay for failure + +**Default Value**: + +.. code-block:: yaml + + 1m0s + + +rate (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Bucket Refill rate per second + +**Default Value**: + +.. code-block:: yaml + + "1000" + + +capacity (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Bucket capacity as number of items + +**Default Value**: + +.. code-block:: yaml + + "10000" + + +config.EventConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +raw-output-policy (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +How output data should be passed along in execution events. + +**Default Value**: + +.. code-block:: yaml + + reference + + +fallback-to-output-reference (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Whether output data should be sent by reference when it is too large to be sent inline in execution events. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.KubeClientConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +qps (float32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "100" + + +burst (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max burst rate for throttle. 0 defaults to 10 + +**Default Value**: + +.. code-block:: yaml + + "25" + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max duration allowed for every request to KubeAPI before giving up. 0 implies no timeout. + +**Default Value**: + +.. code-block:: yaml + + 30s + + +config.LeaderElectionConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enables/Disables leader election. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +lock-config-map (`types.NamespacedName`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +ConfigMap namespace/name to use for resource lock. + +**Default Value**: + +.. code-block:: yaml + + Name: "" + Namespace: "" + + +lease-duration (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration that non-leader candidates will wait to force acquire leadership. This is measured against time of last observed ack. + +**Default Value**: + +.. code-block:: yaml + + 15s + + +renew-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration that the acting master will retry refreshing leadership before giving up. + +**Default Value**: + +.. code-block:: yaml + + 10s + + +retry-period (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Duration the LeaderElector clients should wait between tries of actions. + +**Default Value**: + +.. code-block:: yaml + + 2s + + +types.NamespacedName +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Namespace (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Name (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.NodeConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +default-deadlines (`config.DefaultDeadlines`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value for timeouts + +**Default Value**: + +.. code-block:: yaml + + node-active-deadline: 0s + node-execution-deadline: 0s + workflow-active-deadline: 0s + + +max-node-retries-system-failures (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum number of retries per node for node failure due to infra issues + +**Default Value**: + +.. code-block:: yaml + + "3" + + +interruptible-failure-threshold (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +number of failures for a node to be still considered interruptible. Negative numbers are treated as complementary (ex. -1 means last attempt is non-interruptible).' + +**Default Value**: + +.. code-block:: yaml + + "-1" + + +default-max-attempts (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default maximum number of attempts for a node + +**Default Value**: + +.. code-block:: yaml + + "1" + + +ignore-retry-cause (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Ignore retry cause and count all attempts toward a node's max attempts + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.DefaultDeadlines +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +node-execution-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value of node execution timeout that includes the time spent to run the node/workflow + +**Default Value**: + +.. code-block:: yaml + + 0s + + +node-active-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value of node timeout that includes the time spent queued. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +workflow-active-deadline (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default value of workflow timeout that includes the time spent queued. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +config.Port +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +port (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "10254" + + +Section: qualityofservice +======================================================================================================================== + +tierExecutionValues (map[string]interfaces.QualityOfServiceSpec) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + {} + + +defaultTiers (map[string]string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + {} + + +Section: queues +======================================================================================================================== + +executionQueues (interfaces.ExecutionQueues) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + [] + + +workflowConfigs (interfaces.WorkflowConfigs) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + [] + + +Section: registration +======================================================================================================================== + +maxWorkflowNodes (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "100" + + +maxLabelEntries (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +maxAnnotationEntries (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +workflowSizeLimit (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: remotedata +======================================================================================================================== + +scheme (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + none + + +region (string) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "" + + +signedUrls (`interfaces.SignedURL`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + durationMinutes: 0 + enabled: false + signingPrincipal: "" + + +maxSizeInBytes (int64) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "2097152" + + +inlineEventDataPolicy (int) +------------------------------------------------------------------------------------------------------------------------ + +Specifies how inline execution event data should be saved in the backend + +**Default Value**: + +.. code-block:: yaml + + Offload + + +interfaces.SignedURL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +enabled (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Whether signed urls should even be returned with GetExecutionData, GetNodeExecutionData and GetTaskExecutionData response objects. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +durationMinutes (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + +signingPrincipal (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: scheduler +======================================================================================================================== + +profilerPort (`config.Port`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + 10254 + + +eventScheduler (`interfaces.EventSchedulerConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + aws: null + local: {} + region: "" + scheduleNamePrefix: "" + scheduleRole: "" + scheme: local + targetName: "" + + +workflowExecutor (`interfaces.WorkflowExecutorConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + accountId: "" + aws: null + local: + adminRateLimit: + burst: 10 + tps: 100 + useUTCTz: false + region: "" + scheduleQueueName: "" + scheme: local + + +reconnectAttempts (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +reconnectDelaySeconds (int) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + "0" + + +interfaces.EventSchedulerConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +scheme (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + local + + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +scheduleRole (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +targetName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +scheduleNamePrefix (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +aws (interfaces.AWSSchedulerConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +local (`interfaces.FlyteSchedulerConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + {} + + +interfaces.FlyteSchedulerConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +interfaces.WorkflowExecutorConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +scheme (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + local + + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +scheduleQueueName (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +accountId (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +aws (interfaces.AWSWorkflowExecutorConfig) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +local (`interfaces.FlyteWorkflowExecutorConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + adminRateLimit: + burst: 10 + tps: 100 + useUTCTz: false + + +interfaces.FlyteWorkflowExecutorConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +adminRateLimit (`interfaces.AdminRateLimit`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + burst: 10 + tps: 100 + + +useUTCTz (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +interfaces.AdminRateLimit +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +tps (float64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "100" + + +burst (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "10" + + +Section: secrets +======================================================================================================================== + +secrets-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +Prefix where to look for secrets file + +**Default Value**: + +.. code-block:: yaml + + /etc/secrets + + +env-prefix (string) +------------------------------------------------------------------------------------------------------------------------ + +Prefix for environment variables + +**Default Value**: + +.. code-block:: yaml + + FLYTE_SECRET_ + + +Section: server +======================================================================================================================== + +httpPort (int) +------------------------------------------------------------------------------------------------------------------------ + +On which http port to serve admin + +**Default Value**: + +.. code-block:: yaml + + "8088" + + +grpcPort (int) +------------------------------------------------------------------------------------------------------------------------ + +deprecated + +**Default Value**: + +.. code-block:: yaml + + "0" + + +grpcServerReflection (bool) +------------------------------------------------------------------------------------------------------------------------ + +deprecated + +**Default Value**: + +.. code-block:: yaml + + "false" + + +kube-config (string) +------------------------------------------------------------------------------------------------------------------------ + +Path to kubernetes client config file, default is empty, useful for incluster config. + +**Default Value**: + +.. code-block:: yaml + + "" + + +master (string) +------------------------------------------------------------------------------------------------------------------------ + +The address of the Kubernetes API server. + +**Default Value**: + +.. code-block:: yaml + + "" + + +security (`config.ServerSecurityOptions`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + allowCors: true + allowedHeaders: + - Content-Type + - flyte-authorization + allowedOrigins: + - '*' + auditAccess: false + secure: false + ssl: + certificateFile: "" + keyFile: "" + useAuth: false + + +grpc (`config.GrpcConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + enableGrpcHistograms: false + maxMessageSizeBytes: 0 + port: 8089 + serverReflection: true + + +thirdPartyConfig (`config.ThirdPartyConfigOptions`_) +------------------------------------------------------------------------------------------------------------------------ + +Deprecated please use auth.appAuth.thirdPartyConfig instead. + +**Default Value**: + +.. code-block:: yaml + + flyteClient: + audience: "" + clientId: "" + redirectUri: "" + scopes: [] + + +dataProxy (`config.DataProxyConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Defines data proxy configuration. + +**Default Value**: + +.. code-block:: yaml + + download: + maxExpiresIn: 1h0m0s + upload: + defaultFileNameLength: 20 + maxExpiresIn: 1h0m0s + maxSize: 6Mi + storagePrefix: "" + + +readHeaderTimeoutSeconds (int) +------------------------------------------------------------------------------------------------------------------------ + +The amount of time allowed to read request headers. + +**Default Value**: + +.. code-block:: yaml + + "32" + + +kubeClientConfig (`config.KubeClientConfig (kubeClientConfig)`_) +------------------------------------------------------------------------------------------------------------------------ + +Configuration to control the Kubernetes client + +**Default Value**: + +.. code-block:: yaml + + burst: 25 + qps: 100 + timeout: 30s + + +config.DataProxyConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +upload (`config.DataProxyUploadConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines data proxy upload configuration. + +**Default Value**: + +.. code-block:: yaml + + defaultFileNameLength: 20 + maxExpiresIn: 1h0m0s + maxSize: 6Mi + storagePrefix: "" + + +download (`config.DataProxyDownloadConfig`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Defines data proxy download configuration. + +**Default Value**: + +.. code-block:: yaml + + maxExpiresIn: 1h0m0s + + +config.DataProxyDownloadConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +maxExpiresIn (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum allowed expiration duration. + +**Default Value**: + +.. code-block:: yaml + + 1h0m0s + + +config.DataProxyUploadConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +maxSize (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum allowed upload size. + +**Default Value**: + +.. code-block:: yaml + + 6Mi + + +maxExpiresIn (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum allowed expiration duration. + +**Default Value**: + +.. code-block:: yaml + + 1h0m0s + + +defaultFileNameLength (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Default length for the generated file name if not provided in the request. + +**Default Value**: + +.. code-block:: yaml + + "20" + + +storagePrefix (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Storage prefix to use for all upload requests. + +**Default Value**: + +.. code-block:: yaml + + "" + + +config.GrpcConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +port (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +On which grpc port to serve admin + +**Default Value**: + +.. code-block:: yaml + + "8089" + + +serverReflection (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable GRPC Server Reflection + +**Default Value**: + +.. code-block:: yaml + + "true" + + +maxMessageSizeBytes (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The max size in bytes for incoming gRPC messages + +**Default Value**: + +.. code-block:: yaml + + "0" + + +enableGrpcHistograms (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable grpc histograms + +**Default Value**: + +.. code-block:: yaml + + "false" + + +config.KubeClientConfig (kubeClientConfig) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +qps (int32) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max QPS to the master for requests to KubeAPI. 0 defaults to 5. + +**Default Value**: + +.. code-block:: yaml + + "100" + + +burst (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max burst rate for throttle. 0 defaults to 10 + +**Default Value**: + +.. code-block:: yaml + + "25" + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Max duration allowed for every request to KubeAPI before giving up. 0 implies no timeout. + +**Default Value**: + +.. code-block:: yaml + + 30s + + +config.ServerSecurityOptions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +secure (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +ssl (`config.SslOptions`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + certificateFile: "" + keyFile: "" + + +useAuth (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +auditAccess (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "false" + + +allowCors (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "true" + + +allowedOrigins ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + - '*' + + +allowedHeaders ([]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + - Content-Type + - flyte-authorization + + +config.SslOptions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +certificateFile (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +keyFile (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "" + + +Section: storage +======================================================================================================================== + +type (string) +------------------------------------------------------------------------------------------------------------------------ + +Sets the type of storage to configure [s3/minio/local/mem/stow]. + +**Default Value**: + +.. code-block:: yaml + + s3 + + +connection (`storage.ConnectionConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + access-key: "" + auth-type: iam + disable-ssl: false + endpoint: "" + region: us-east-1 + secret-key: "" + + +stow (`storage.StowConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Storage config for stow backend. + +**Default Value**: + +.. code-block:: yaml + + {} + + +container (string) +------------------------------------------------------------------------------------------------------------------------ + +Initial container (in s3 a bucket) to create -if it doesn't exist-.' + +**Default Value**: + +.. code-block:: yaml + + "" + + +enable-multicontainer (bool) +------------------------------------------------------------------------------------------------------------------------ + +If this is true, then the container argument is overlooked and redundant. This config will automatically open new connections to new containers/buckets as they are encountered + +**Default Value**: + +.. code-block:: yaml + + "false" + + +cache (`storage.CachingConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + max_size_mbs: 0 + target_gc_percent: 0 + + +limits (`storage.LimitsConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets limits for stores. + +**Default Value**: + +.. code-block:: yaml + + maxDownloadMBs: 2 + + +defaultHttpClient (`storage.HTTPClientConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets the default http client config. + +**Default Value**: + +.. code-block:: yaml + + headers: null + timeout: 0s + + +signedUrl (`storage.SignedURLConfig`_) +------------------------------------------------------------------------------------------------------------------------ + +Sets config for SignedURL. + +**Default Value**: + +.. code-block:: yaml + + {} + + +storage.CachingConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +max_size_mbs (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum size of the cache where the Blob store data is cached in-memory. If not specified or set to 0, cache is not used + +**Default Value**: + +.. code-block:: yaml + + "0" + + +target_gc_percent (int) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets the garbage collection target percentage. + +**Default Value**: + +.. code-block:: yaml + + "0" + + +storage.ConnectionConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +endpoint (`config.URL`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +URL for storage client to connect to. + +**Default Value**: + +.. code-block:: yaml + + "" + + +auth-type (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Auth Type to use [iam,accesskey]. + +**Default Value**: + +.. code-block:: yaml + + iam + + +access-key (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Access key to use. Only required when authtype is set to accesskey. + +**Default Value**: + +.. code-block:: yaml + + "" + + +secret-key (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Secret to use when accesskey is set. + +**Default Value**: + +.. code-block:: yaml + + "" + + +region (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Region to connect to. + +**Default Value**: + +.. code-block:: yaml + + us-east-1 + + +disable-ssl (bool) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Disables SSL connection. Should only be used for development. + +**Default Value**: + +.. code-block:: yaml + + "false" + + +storage.HTTPClientConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +headers (map[string][]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +timeout (`config.Duration`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets time out on the http client. + +**Default Value**: + +.. code-block:: yaml + + 0s + + +storage.LimitsConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +maxDownloadMBs (int64) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Maximum allowed download size (in MBs) per call. + +**Default Value**: + +.. code-block:: yaml + + "2" + + +storage.SignedURLConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +stowConfigOverride (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + null + + +storage.StowConfig +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +kind (string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Kind of Stow backend to use. Refer to github/flyteorg/stow + +**Default Value**: + +.. code-block:: yaml + + "" + + +config (map[string]string) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Configuration for stow backend. Refer to github/flyteorg/stow + +**Default Value**: + +.. code-block:: yaml + + {} + + +Section: task_resources +======================================================================================================================== + +defaults (`interfaces.TaskResourceSet`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + cpu: "2" + ephemeralStorage: "0" + gpu: "0" + memory: 200Mi + storage: "0" + + +limits (`interfaces.TaskResourceSet`_) +------------------------------------------------------------------------------------------------------------------------ + +**Default Value**: + +.. code-block:: yaml + + cpu: "2" + ephemeralStorage: "0" + gpu: "1" + memory: 1Gi + storage: "0" + + +interfaces.TaskResourceSet +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +cpu (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "2" + + +gpu (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + +memory (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + 200Mi + + +storage (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + +ephemeralStorage (`resource.Quantity`_) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**Default Value**: + +.. code-block:: yaml + + "0" + + diff --git a/docs/deployment/configuration/index.md b/docs/deployment/configuration/index.md new file mode 100644 index 0000000000..9eec838596 --- /dev/null +++ b/docs/deployment/configuration/index.md @@ -0,0 +1,66 @@ +(deployment-configuration)= + +# Configuration + +This section will cover how to configure your Flyte cluster for features like +authentication, monitoring, and notifications. + +````{important} +The configuration instructions in this section are for the `flyte` and `flyte-core` Helm charts, which is for +the {ref}`multi-cluster setup `. + +If you're using the `flyte-binary` chart for the {ref}`single cluster setup `, +instead of specifying configuration under a yaml file like `cloud_events.yaml` in {ref}`deployment-configuration-cloud-event`, +you'll need to add the configuration settings under the `inline` section in the `eks-production.yaml` file: + +```{eval-rst} +.. literalinclude:: ../../../charts/flyte-binary/eks-production.yaml + :language: yaml + :lines: 30-41 + :caption: charts/flyte-binary/eks-production.yaml +``` + +```` + + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {ref}`Authenticating in Flyte ` + - Basic OIDC and Authentication Setup +* - {ref}`Migrating Your Authentication Config ` + - Migration guide to move to Admin's own authorization server. +* - {ref}`Understanding Authentication ` + - Migration guide to move to Admin's own authorization server. +* - {ref}`Configuring Custom K8s Resources ` + - Use Flyte's cluster-resource-controller to control specific Kubernetes resources and administer project/domain-specific CPU/GPU/memory resource quotas. +* - {ref}`Adding New Customizable Resources ` + - Create new default configurations or overriding certain values for specific combinations of user projects, domains and workflows through Flyte APIs. +* - {ref}`Notifications ` + - Guide to setting up and configuring notifications. +* - {ref}`External Events ` + - How to set up Flyte to emit events to third-parties. +* - {ref}`Monitoring ` + - Guide to setting up and configuring observability. +* - {ref}`Optimizing Performance ` + - Improve the performance of the core Flyte engine. +* - {ref}`Platform Events ` + - Configure Flyte to to send events to external pub/sub systems. +``` + +```{toctree} +:maxdepth: 1 +:name: Cluster Config +:hidden: + +auth_setup +auth_migration +auth_appendix +general +customizable_resources +monitoring +notifications +performance +cloud_event +``` diff --git a/docs/deployment/configuration/monitoring.rst b/docs/deployment/configuration/monitoring.rst new file mode 100644 index 0000000000..75bc89adc4 --- /dev/null +++ b/docs/deployment/configuration/monitoring.rst @@ -0,0 +1,99 @@ +.. _deployment-configuration-monitoring: + +Monitoring +---------- + +.. tags:: Infrastructure, Advanced + +.. tip:: The Flyte core team publishes and maintains Grafana dashboards built using Prometheus data sources, which can be found `here `__. + +Metrics for Executions +====================== + +Flyte-provided Metrics +~~~~~~~~~~~~~~~~~~~~~~ + +Whenever you run a workflow, Flyte platform automatically emits high-level metrics. These metrics follow a consistent schema and aim to provide visibility into aspects of the platform which might otherwise be opaque. +These metrics help users diagnose whether an issue is inherent to the platform or one's own task or workflow implementation. + +We will be adding to this set of metrics as we implement the capabilities to pull more data from the system, so keep checking back for new stats! + +At a high level, workflow execution goes through the following discrete steps: + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/deployment/monitoring/flyte_wf_timeline.svg?sanitize=true + +=================================== ================================================================================================================================== + Description of main events for workflow execution +----------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Events Description +=================================== ================================================================================================================================== +Acceptance Measures the time consumed from receiving a service call to creating an Execution (Unknown) and moving to QUEUED. +Transition Latency Measures the latency between two consecutive node executions; the time spent in Flyte engine. +Queuing Latency Measures the latency between the node moving to QUEUED and the handler reporting the executable moving to RUNNING state. +Task Execution Actual time spent executing the user code. +Repeat steps 2-4 for every task +Transition Latency See #2 +Completion Latency Measures the time consumed by a workflow moving from SUCCEEDING/FAILING state to TERMINAL state. +=================================== ================================================================================================================================== + + +========================================================== =========== =============================================================================================================================================================== + Flyte Stats Schema +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Prefix Type Description +========================================================== =========== =============================================================================================================================================================== +``propeller.all.workflow.acceptance-latency-ms`` Timer (ms) Measures the time consumed from receiving a service call to creating an Execution (Unknown) and moving to QUEUED. +``propeller.all.node.queueing-latency-ms`` Timer (ms) Measures the latency between the node moving to QUEUED and the handler reporting the executable moving to RUNNING state. +``propeller.all.node.transition-latency-ms`` Timer (ms) Measures the latency between two consecutive node executions; the time spent in Flyte engine. +``propeller.all.workflow.completion-latency-ms`` Timer (ms) Measures the time consumed by a workflow moving from SUCCEEDING/FAILING state to TERMINAL state. +``propeller.all.node.success-duration-ms`` Timer (ms) Actual time spent executing user code (when the node ends with SUCCESS state). +``propeller.all.node.success-duration-ms-count`` Counter The number of times a node success has been reported. +``propeller.all.node.failure-duration-ms`` Timer (ms) Actual time spent executing user code (when the node ends with FAILURE state). +``propeller.all.node.failure-duration-ms-count`` Counter The number of times a node failure has been reported. + +========================================================== =========== =============================================================================================================================================================== + +All the above stats are automatically tagged with the following fields for further scoping. This includes user-produced stats. +Users can also provide additional tags (or override tags) for custom stats. + +.. _task_stats_tags: + +=============== ================================================================================= + Flyte Stats Tags +-------------------------------------------------------------------------------------------------- + Tag Description +=============== ================================================================================= +wf Name of the workflow that was executing when this metric was emitted. + ``{{project}}:{{domain}}:{{workflow_name}}`` +=============== ================================================================================= + +User Stats With Flyte +~~~~~~~~~~~~~~~~~~~~~~ + +The workflow parameters object that the SDK injects into various tasks has a ``statsd`` handle that users should call +to emit stats of their workflows not captured by the default metrics. The usual caveats around cardinality apply, of course. + +.. todo: Reference to Flytekit task stats + +Users are encouraged to avoid creating their own stats handlers. +If not done correctly, these can pollute the general namespace and accidentally interfere with the production stats of live services, causing pages and wreaking havoc. +If you're using any libraries that emit stats, it's best to turn them off if possible. + + +Use Published Dashboards to Monitor Flyte Deployment +==================================================== + +Flyte Backend is written in Golang and exposes stats using Prometheus. The stats are labeled with workflow, task, project & domain, wherever appropriate. + +The dashboards are divided into two types: + +- **User-facing dashboards**: Dashboards that can be used to triage/investigate/observe performance and characteristics of workflows and tasks. + The user-facing dashboard is published under Grafana marketplace ID `13980 `__. + +- **System Dashboards**: Dashboards that are useful for the system maintainer to maintain their Flyte deployments. These are further divided into: + - DataPlane/FlytePropeller dashboards published @ `13979 `__ + - ControlPlane/Flyteadmin dashboards published @ `13981 `__ + +The above mentioned are basic dashboards and do no include all the metrics exposed by Flyte. +Please help us improve the dashboards by contributing to them 🙏. +Refer to the build scripts `here `__. \ No newline at end of file diff --git a/docs/deployment/configuration/notifications.rst b/docs/deployment/configuration/notifications.rst new file mode 100644 index 0000000000..386e19a406 --- /dev/null +++ b/docs/deployment/configuration/notifications.rst @@ -0,0 +1,135 @@ +.. _deployment-configuration-notifications: + +Notifications +------------- + +.. tags:: Infrastructure, Advanced + +When a workflow completes, users can be notified by email, `Pagerduty `__, +or `Slack `__. + +The content of these notifications is configurable at the platform level. + +***** +Usage +***** + +When a workflow reaches a specified `terminal workflow execution phase `__ +the :py:class:`flytekit:flytekit.Email`, :py:class:`flytekit:flytekit.PagerDuty`, or :py:class:`flytekit:flytekit.Slack` +objects can be used in the construction of a :py:class:`flytekit:flytekit.LaunchPlan`. + +For example + +.. code:: python + + from flytekit import Email, LaunchPlan + from flytekit.models.core.execution import WorkflowExecutionPhase + + # This launch plan triggers email notifications when the workflow execution it triggered reaches the phase `SUCCEEDED`. + my_notifiying_lp = LaunchPlan.create( + "my_notifiying_lp", + my_workflow_definition, + default_inputs={"a": 4}, + notifications=[ + Email( + phases=[WorkflowExecutionPhase.SUCCEEDED], + recipients_email=["admin@example.com"], + ) + ], + ) + + +See detailed usage examples in the :std:doc:`User Guide ` + +Notifications can be combined with schedules to automatically alert you when a scheduled job succeeds or fails. + +Future work +=========== + +Work is ongoing to support a generic event egress system that can be used to publish events for tasks, workflows and +workflow nodes. When this is complete, generic event subscribers can asynchronously process these vents for a rich +and fully customizable experience. + + +****************************** +Platform Configuration Changes +****************************** + +Setting Up Workflow Notifications +================================= + +The ``notifications`` top-level portion of the FlyteAdmin config specifies how to handle notifications. + +As with schedules, the notifications handling is composed of two parts. One handles enqueuing notifications asynchronously and the second part handles processing pending notifications and actually firing off emails and alerts. + +This is only supported for Flyte instances running on AWS. + +Config +======= + +To publish notifications, you'll need to set up an `SNS topic `_. + +In order to process notifications, you'll need to set up an `AWS SQS `_ queue to consume notification events. This queue must be configured as a subscription to your SNS topic you created above. + +In order to actually publish notifications, you'll need a `verified SES email address `_ which will be used to send notification emails and alerts using email APIs. + +The role you use to run FlyteAdmin must have permissions to read and write to your SNS topic and SQS queue. + +Let's look at the following config section and explain what each value represents: + +.. code-block:: yaml + + notifications: + # Because AWS is the only cloud back-end supported for executing scheduled + # workflows in this case, only ``"aws"`` is a valid value. By default, the + #no-op executor is used. + type: "aws" + + # This specifies which region AWS clients will use when creating SNS and SQS clients. + region: "us-east-1" + + # This handles pushing notification events to your SNS topic. + publisher: + + # This is the arn of your SNS topic. + topicName: "arn:aws:sns:us-east-1:{{ YOUR ACCOUNT ID }}:{{ YOUR TOPIC }}" + + # This handles the recording notification events and enqueueing them to be + # processed asynchronously. + processor: + + # This is the name of the SQS queue which will capture pending notification events. + queueName: "{{ YOUR QUEUE NAME }}" + + # Your AWS `account id, see: https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html#FindingYourAWSId + accountId: "{{ YOUR ACCOUNT ID }}" + + # This section encloses config details for sending and formatting emails + # used as notifications. + emailer: + + # Configurable subject line used in notification emails. + subject: "Notice: Execution \"{{ workflow.name }}\" has {{ phase }} in \"{{ domain }}\"." + + # Your verified SES email sender. + sender: "flyte-notifications@company.com" + + # Configurable email body used in notifications. + body: > + Execution \"{{ workflow.name }} [{{ name }}]\" has {{ phase }} in \"{{ domain }}\". View details at + + http://flyte.company.com/console/projects/{{ project }}/domains/{{ domain }}/executions/{{ name }}. {{ error }} + +The full set of parameters which can be used for email templating are checked +into `code `_. + +.. _admin-config-example: + +Example config +============== + +You can find the full configuration file `here `__. + +.. rli:: https://raw.githubusercontent.com/flyteorg/flyteadmin/master/flyteadmin_config.yaml + :caption: flyteadmin/flyteadmin_config.yaml + :lines: 91-105 diff --git a/docs/deployment/configuration/performance.rst b/docs/deployment/configuration/performance.rst new file mode 100644 index 0000000000..ee65cdaa20 --- /dev/null +++ b/docs/deployment/configuration/performance.rst @@ -0,0 +1,264 @@ +.. _deployment-configuration-performance: + +###################################################### +Optimizing Performance +###################################################### + +.. tags:: Infrastructure, Kubernetes, Advanced + +.. tip:: Before getting started, it is always important to measure the performance. Flyte project publishes and manages some grafana templates as described in - :ref:`deployment-configuration-monitoring`. + +The video below contains an overview of the Flyte architecture, what is meant by "performance", details of one loop in FlytePropeller, and a demo of the Grafana Labs dashboard. + +.. youtube:: FJ-rG9lZDhY + +Scaling up FlytePropeller +========================== +`FlytePropeller `_ is the core engine of Flyte that executes the workflows for Flyte. +It is designed as a `Kubernetes Controller `_, where the desired state is specified as a FlyteWorkflow `Custom Resource `_. + +One of the base assumptions of FlytePropeller is that every workflow is independent and can be executed by a completely distinct process, without a need for communication with other processes. Meanwhile, one workflow tracks the dependencies between tasks using a DAG structure and hence constantly needs synchronization. +Currently, FlytePropeller executes Workflows by using an event loop to periodically track and amend the execution status. Within each iteration, a single thread requests the state of Workflow nodes and performs operations (i.e., scheduling node executions, handling failures, etc) to gracefully transition a Workflow from the observed state to the desired state (i.e., Success). Consequently, actual node executions are performed by various FlytePlugins, a diverse collection of operations spanning k8s and other remote services, and FlytePropeller is only responsible for effectively monitoring and managing these executions. + +FlytePropeller has a lot of knobs that can be tweaked for performance. The default configuration is usually adequate for small to medium sized installations of Flyte, that are running about 500 workflows concurrently with no noticeable overhead. In the case when the number of workflows increases, +FlytePropeller will automatically slow down, without losing correctness. + +Signs of slowdown +------------------ + +.. list-table:: Important metrics to look out for in Prometheus dashboard + :widths: 25 25 50 100 + :header-rows: 1 + + * - Metric + - Dashboard + - Alerting factor + - Effect + * - ``flyte:propeller:all:free_workers_count`` + - Flyte Propeller Dashboard + - Number of free-workers in all FlytePropeller instances are very low. + - This will increase overall latency for Each workflow propagation + * - ``sum(rate(flyte:propeller:all:round:raw_ms[5m])) by (wf)`` + - Flyte Propeller Dashboard + - Round Latency for Each workflow increases + - Flyte propeller is taking more time to process each workflow + * - ``sum(rate(flyte:propeller:all:main_depth[5m]))`` + - Flyte Propeller Dashboard + - Workflows take longer to start or slow + - The processing queue depth is long and is taking long to drain + +For each of the metrics above you can dig deeper into the cause for this spike in latency. All of them are mostly related to one latency and should be correlated - ``The Round latency!``. +The round-latency is the time it takes for FlytePropeller to to perform a single iteration of workflow evaluation. To understand this, you have to understand the :ref:`divedeep-execution-timeline`. Once you understand this, continue reading on. + +Optimizing round latency +------------------------- + +Optimize FlytePropeller configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Usually round-latency can be resolved by adjusting FlytePropeller config specified `here `_ or sometimes adjusting the global defaults for your deployment or per workflow-execution. +Let us first look at various config properties that can be set and would impact the performance of one round in Flyte and should be tweaked + +.. list-table:: Important Properties + :widths: 25 25 25 50 + :header-rows: 1 + + * - Property + - Section + - Rule of thumb + - Description + * - ``workers`` + - propeller + - Larger the number, implies more workflows can be evaluated in parallel. But it should depend on number of CPU cores assigned to FlytePropeller and evaluated against the cost of context switching. A number usually < 500 - 800 with 4-8 cpu cores works fine. + - Number of `logical threads` workers, that can work concurrently. Also implies number of workflows that can be executed in parallel. Since FlytePropeller uses go-routines, it can run way more than number of physical cores. + * - ``workflow-reeval-duration`` + - propeller + - lower the number - lower latency, lower throughput (low throughput is because the same workflow will be evaluated more times) + - frequency at which, given no external signal, a workflow should be re-evaluated by Flyte propellers reval loop + * - ``downstream-eval-duration`` + - propeller + - lower the number - lower latency and lower throughput (low throughput is because the same workflow will be evaluated more times) + - This indicates how often are external events like pods completion etc recorded. + * - ``max-streak-length`` + - propeller + - higher the number lower the latency for end to end workflow, especially for cached workflows + - number of consecutive rounds to try with one workflow - prioritize a hot workflow over others. + * - ``kube-client-config`` + - propeller + - This is how you can control the number of requests ceiling that FlytePropeller can initiate to KubeAPI. This is usual the #1 bottle neck + - this configures the kubernetes client used by FlytePropeller + * - ``workflowStore.policy`` + - propeller + - This config uses a trick in etcD to minimize number of redundant loops in FlytePropeller, thus improving free slots + - Use this to configure how FlytePropeller should evaluate workflows, the default is usually a good choice + * - ``storage.cache`` + - propeller + - This config is used to configure the write-through cache used by FlytePropeller on top of the metastore + - FlytePropeller uses the configure blob-store (can be changed to something more performant in the future) to optimize read and write latency, for all metadata IO operations. Metadata refers to the input and output pointers + * - ``admin-launcher.tps``, ``admin-launcher.cacheSize``, ``admin-launcher.workers`` + - propeller + - This config is used to configure the max rate and launch-plans that FlytePropeller can launch against FlyteAdmin + - It is essential to limit the number of writes from FlytePropeller to flyteadmin to prevent brown-outs or request throttling at the server. Also the cache reduces number of calls to the server. + * - ``tasks.backoff.max-duration`` + - propeller + - This config is used to configure the maximum back-off interval in case of resource-quota errors + - FlytePropeller will automatically back-off when k8s or other services request it to slowdown or when desired quotas are met. + * - ``max-parallelism`` + - admin, per workflow, per execution + - Refer to examples and documentation below + - docs below + + +In the above table the 2 most important configs are ``workers`` and ``kube-client-config``. + +The Kube client config controls the request throughput from FlytePropeller to the Kube API server. These requests may include creating/monitoring Pods or creating/updating FlyteWorkflow CRDs to track workflow execution. The default configuration (provided by k8s) contains very steep rate-limiting, and therefore FlytePropeller provides a default configuration that offers better performance. However, if your workload involves larger scales (e.g., >5k fanout dynamic or map tasks, >8k concurrent workflows, etc.,) the Kube client config rate limiting may still contribute to a noticeable drop in performance. Increasing the ``qps`` and ``burst`` values may help alleviate back pressure and improve FlytePropeller performance. An example of Kube-client-config is as follows: + +.. code-block:: yaml + + propeller: + kube-client-config: + qps: 100 # Refers to max rate of requests to KubeAPI server + burst: 50 # refers to max burst rate to Kube API server + timeout: 30s # Refers to timeout when talking with kubeapi server + + +.. note:: As you increase the number of workers in FlytePropeller it is important to increase the number of cpu's given to FlytePropeller pod. + +It is worth noting that the Kube API server tends to throttle requests transparently. This means that while tweaking performance by increasing the allowed frequency of Kube API server requests (e.g., increasing FlytePropeller workers or relaxing Kube client config rate-limiting), there may be steep performance decreases for no apparent reason. Looking at the Kube API server request queue metrics in these cases can assist in identifying whether throttling is to blame. Unfortunately, there is no one-size-fits-all solution here, and customizing these parameters for your workload will require trial and error. + +Another area of slowdown could be the size of the input-output cache that FlytePropeller maintains in-memory. This can be configured, while configuring +the storage for FlytePropeller. Rule of thumb, for FlytePropeller with x memory limit, allocate x/2 to the cache + +Learn: max-streak-length & ResourceVersionCaching +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Kubernetes controllers often use Informer caches, rather than reading data directly from KubeAPI. This is to prevent excessive requests to KubeAPI server. The caches are eventually consistent, i.e., every write by the controller is eventually replicated to the cache, but there can be time periods, when the cache lags. +Since FlytePropeller, runs Workflow evaluations as an event loop, which is triggered by any changes to one of the resources that a workflow spawned. +It is possible that a Workflow will be evaluated, even when the last write has not yet propagated to the Informer cache. EtcD also does not allow stale writes, i.e., writes with an object that is older than the object that was written. This is maintained using a server side vector-clock - called the resource version. +Stale writes are writes when the evaluation resulted in a mutation of an object that is older than the object recorded in etcD. +These stale writes often lead to conflicts and hence increase load on the KubeAPI server and on FlytePropeller as the workers are busy writing stale objects repeatedly. + +To prevent this duplication and redundancy, FlytePropeller employs a trick. For every write, it records the last known version number in the database and then tries to wait for the change to propagate to the informer cache. + +If `max-streaks` are enabled then instead of waiting for the informer cache to be refreshed, FlytePropeller uses its own inmemory copy to run multiple rounds as long as mutations occur or the max-streak-length configuration is met. This reduces the latency of cache propagation, which can be order of seconds. + +Worst case workflows: Poison Pills & max-parallelism +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The worst case for FlytePropeller is workflows that have an extremely large fan-out. This is because FlytePropeller implements a greedy traversal algorithm, that tries to evaluate the entire unblocked nodes within a workflow in every round. +A solution for this is to limit the maximum number of nodes that can be evaluated. This can be done by setting max-parallelism for an execution. +This can done in multiple ways + +#. Platform default: This allows to set platform-wide defaults for maximum concurrency within a Workflow execution. This can be overridden per Launch plan or per execution. + The default `maxParallelism is configured to be 25 `_. + It can be overridden with this config block in flyteadmin + + .. code-block:: yaml + + flyteadmin: + maxParallelism: 25 + +#. Default for a specific launch plan. For any launch plan, the maxParallelism value can be changed or altered. This can be done using :py:meth:`flytekit.LaunchPlan.get_or_create` or the :std:ref:`ref_flyteidl.admin.LaunchPlanCreateRequest` + **Flytekit Example** + + .. code-block:: python + + LaunchPlan.get_or_create( + name="my_cron_scheduled_lp", + workflow=date_formatter_wf, + max_parallelism=30, + ) + +#. Specify for an execution. For any specific execution the max-parallelism can be overridden. This can be done using flytectl (and soon flyteconsole). Refer to :std:ref:`flyteCtl docs ` + + + + +Scaling out FlyteAdmin +======================= +FlyteAdmin is a stateless service. Often time before needing to scale FlyteAdmin, you need to scale the backing database. Check out the FlyteAdmin Dashboard to see signs of latency degradation and increase the size of backing postgres instance. +FlyteAdmin is a stateless service and its replicas (in the kubernetes deployment) can be simply increased to allow higher throughput. + +Scaling out Datacatalog +======================== +Datacatalog is a stateless service. Often time before needing to scale Datacatalog, you need to scale the backing database. Check out the Datacatalog Dashboard to see signs of latency degradation and increase the size of backing postgres instance. +Datacatalog is a stateless service and its replicas (in the kubernetes deployment) can be simply increased to allow higher throughput. + +Scaling out FlytePropeller +=========================== + +Manual scale-out +---------------- +FlytePropeller can be run manually per namespace. This is not a recommended solution as it is harder to deploy, but if your organization can deploy and maintain multiple copies of FlytePropeller, you can use this. + +Automatic scale-out +------------------- +FlytePropeller Manager is a new component introduced as part of `this RFC `_ to facilitate horizontal scaling of FlytePropeller through sharding. Effectively, the Manager is responsible for maintaining liveness and proper configuration over a collection of FlytePropeller instances. This scheme uses k8s label selectors to deterministically assign FlyteWorkflow CRD responsibilities to FlytePropeller instances, effectively distributing processing load over the shards. + +Deployment of FlytePropeller Manager requires k8s configuration updates including a modified FlytePropeller Deployment and a new PodTemplate defining managed FlytePropeller instances. The easiest way to apply these updates is by setting the "flytepropeller.manager" value to "true" in the `helm deployment `_ and setting the manager config at "configmap.core.manager". + +Flyte provides a variety of Shard Strategies to configure how FlyteWorkflows are sharded among managed FlytePropeller instances. These include hash, which uses consistent hashing to load-balance evaluation over shards, and project / domain, which map the respective IDs to specific managed FlytePropeller instances. Below we include examples of helm configurations for each of the existing Shard Strategies. + +The Hash Shard Strategy, denoted by "type: hash" in the configuration below, uses consistent hashing to evenly distribute FlyteWorkflows over managed FlytePropeller instances. This configuration requires a "shard-count" variable which defines the number of managed FlytePropeller instances. + +.. code-block:: yaml + + configmap: + core: + # a configuration example using the "hash" shard type + manager: + # pod and scanning configuration redacted + # ... + shard: + type: hash # use the "hash" shard strategy + shard-count: 4 # the total number of shards + +The Project and Domain Shard Strategies, denoted by "type: project" and "type: domain" respectively, use the FlyteWorkflow project and domain metadata to shard FlyteWorkflows. These Shard Strategies are configured using a "per-shard-mapping" option, which is a list of ID lists. Each element in the "per-shard-mapping" list defines a new shard and the ID list assigns responsibility for the specified IDs to that shard. A shard configured as a single wildcard ID (i.e. "*") is responsible for all IDs that are not covered by other shards. Only a single shard may be configured with a wildcard ID and on that shard their must be only one ID, namely the wildcard. + +.. code-block:: yaml + + configmap: + core: + # a configuration example using the "project" shard type + manager: + # pod and scanning configuration redacted + # ... + shard: + type: project # use the "project" shard strategy + per-shard-mapping: # a list of per shard mappings - one shard is created for each element + - ids: # the list of ids to be managed by the first shard + - flytesnacks + - ids: # the list of ids to be managed by the second shard + - flyteexamples + - flytelabs + - ids: # the list of ids to be managed by the third shard + - "*" # use the wildcard to manage all ids not managed by other shards + + configmap: + core: + # a configuration example using the "domain" shard type + manager: + # pod and scanning configuration redacted + # ... + shard: + type: domain # use the "domain" shard strategy + per-shard-mapping: # a list of per shard mappings - one shard is created for each element + - ids: # the list of ids to be managed by the first shard + - production + - ids: # the list of ids to be managed by the second shard + - "*" # use the wildcard to manage all ids not managed by other shards + +Multi-Cluster mode +=================== +In our experience at Lyft, we saw that the Kubernetes cluster would have problems before FlytePropeller or FlyteAdmin would have impact. Thus Flyte supports adding multiple dataplane clusters by default. Each dataplane cluster, has one or more FlytePropellers running in them, and flyteadmin manages the routing and assigning of workloads to these clusters. + + +Improving etcd Performance +=========================== + +Offloading Static Workflow Information from CRD +----------------------------------------------- + +Flyte uses a k8s CRD (Custom Resource Definition) to store and track workflow executions. This resource includes the workflow definition, for example tasks and subworkflows that are involved and the dependencies between nodes, but also includes the execution status of the workflow. The latter information (ie. runtime status) is dynamic, meaning changes during the workflow's execution as nodes transition phases and the workflow execution progresses. However, the former information (ie. workflow definition) remains static, meaning it will never change and is only consulted to retrieve node definitions and workflow dependencies. + +CRDs are stored within etcd, a key-value datastore heavily used in kubernetes. Etcd requires a complete rewrite of the value data every time a single field changes. Consequently, the read / write performance of etcd, as with all key-value stores, is strongly correlated with the size of the data. In Flyte's case, to guarantee only-once execution of nodes we need to persist workflow state by updating the CRD at every node phase change. As the size of a workflow increases this means we are frequently rewriting a large CRD. In addition to poor read / write performance in etcd this update may be restricted by a hard limit on the overall CRD size. + +To counter the challenges of large FlyteWorkflow CRDs Flyte includes a configuration option to offload the static portions of the CRD (ie. workflow / task / subworkflow definitions and node dependencies) to the blobstore. This functionality can be enabled by setting the ``useOffloadedWorkflowClosure`` option to ``true`` in the `FlyteAdmin configuration `_. When set, the FlyteWorkflow CRD will populate a ``WorkflowClosureReference`` field on the CRD with the location of the static data and FlytePropeller will read this information (through a cache) during each workflow evaluation. One important note is that currently this requires FlyteAdmin and FlytePropeller to have access to the same blobstore since FlyteAdmin only specifies a blobstore location in the CRD. diff --git a/docs/deployment/deployment/cloud_production.rst b/docs/deployment/deployment/cloud_production.rst new file mode 100644 index 0000000000..1736f1eb4c --- /dev/null +++ b/docs/deployment/deployment/cloud_production.rst @@ -0,0 +1,87 @@ +.. _deployment-deployment-cloud-production: + +################################################# +Single Cluster Production-grade Cloud Deployment +################################################# + +.. tags:: Kubernetes, Infrastructure, Advanced + +The following guide assumes you've successfully set up a +:ref:`Single Cluster Simple Cloud Deployment `. + +This guide describes additional setup steps to productionize your Flyte +deployment. While not strictly required, we recommend that you incorporate these +changes. + +*********** +Ingress/DNS +*********** + +Assuming your cluster has an existing Ingress controller, Flyte will be +accessible without port forwarding. The base chart installed in the previous +guide already contains the ingress rules, but they are not enabled by default. + +To turn on ingress, update your ``values.yaml`` file to include the following block. + +.. tabs:: + + .. group-tab:: ``flyte-binary`` on EKS using NGINX + + .. literalinclude:: ../../../charts/flyte-binary/eks-production.yaml + :caption: charts/flyte-binary/eks-production.yaml + :language: yaml + :lines: 127-135 + + .. group-tab:: ``flyte-binary``/ on EKS using ALB + + .. code-block:: yaml + + ingress: + create: true + commonAnnotations: + alb.ingress.kubernetes.io/certificate-arn: '' + alb.ingress.kubernetes.io/group.name: flyte + alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' + alb.ingress.kubernetes.io/scheme: internet-facing + alb.ingress.kubernetes.io/ssl-redirect: '443' + alb.ingress.kubernetes.io/target-type: ip + kubernetes.io/ingress.class: alb + httpAnnotations: + alb.ingress.kubernetes.io/actions.app-root: '{"Type": "redirect", "RedirectConfig": {"Path": "/console", "StatusCode": "HTTP_302"}}' + grpcAnnotations: + alb.ingress.kubernetes.io/backend-protocol-version: GRPC + host: #use a DNS CNAME pointing to your ALB + + .. group-tab:: ``flyte-core`` on GCP using NGINX + + .. literalinclude:: ../../../charts/flyte-core/values-gcp.yaml + :caption: charts/flyte-core/values-gcp.yaml + :language: yaml + :lines: 156-164 + + +*************** +Authentication +*************** + +Authentication comes with Flyte in the form of OAuth 2.0. Please see the +`authentication guide `__ for instructions. + +.. note:: + + Authorization is not supported out-of-the-box in Flyte. This is due to the + wide and variety of authorization requirements that different organizations use. + +*************** +Upgrade Path +*************** + +To upgrade, simply ``helm upgrade`` your relevant chart. + +One thing to keep in mind during upgrades is that Flyte is released regularly +using semantic versioning. Since Flyte ``1.0.0`` will be with us for a while, +you should expect large changes in minor version bumps, which backwards +compatibility being maintained, for the most part. + +If you're using the :ref:`multi-cluster ` +deployment model for Flyte, components should be upgraded together. diff --git a/docs/deployment/deployment/cloud_simple.rst b/docs/deployment/deployment/cloud_simple.rst new file mode 100644 index 0000000000..b280546708 --- /dev/null +++ b/docs/deployment/deployment/cloud_simple.rst @@ -0,0 +1,132 @@ +.. _deployment-deployment-cloud-simple: + +####################################### +Single Cluster Simple Cloud Deployment +####################################### + +.. tags:: Kubernetes, Infrastructure, Basic + +These instructions are suitable for the main cloud providers. + +**************** +Prerequisites +**************** +In order to install Flyte, you will need access to the following: + +* A Kubernetes cluster: `EKS `__, + `GKE `__, etc. +* At least one blob storage bucket: `S3 `__, + `GCS `__, etc. +* A Postgres database: `RDS `__, + `CloudSQL `__, etc. +* At least one IAM role on `AWS `__, + `GCP `__, etc. This is the role for the Flyte + backend service to assume. You can provision another role for user code to assume as well. + +As Flyte documentation cannot keep up with the pace of change of the cloud +provider APIs, please refer to their official documentation for each of +these prerequisites. + +.. note:: + + `Union.AI `__ plans to open-source a reference + implementation of these requirements for the major cloud providers in early + 2023. + +*************** +Installation +*************** + +Flyte is installed via a `Helm `__ chart. First, add the Flyte +chart repo to Helm: + +.. prompt:: bash $ + + helm repo add flyteorg https://flyteorg.github.io/flyte + +Then download and update the values files: + +.. prompt:: bash $ + + curl -sL https://raw.githubusercontent.com/flyteorg/flyte/master/charts/flyte-binary/eks-starter.yaml + +Finally, install the chart: + +.. prompt:: bash $ + + helm install flyte-backend flyteorg/flyte-binary \ + --dry-run --namespace flyte --values eks-starter.yaml + +When ready to install, remove the ``--dry-run`` switch. + +Verify the Installation +======================= + +The values supplied by the ``eks-starter.yaml`` file provides only the simplest +installation of Flyte. The core functionality and scalability of Flyte will be +there, but no plugins are included (e.g. Spark tasks will not work), there is no +DNS or SSL, and there is no authentication. + +Port Forward Flyte Service +-------------------------- + +To verify the installation therefore you'll need to port forward the Kubernetes service. + +.. prompt:: bash $ + + kubectl -n flyte port-forward service/flyte-binary 8088:8088 8089:8089 + +You should be able to navigate to http://localhost:8088/console. + +The Flyte server operates on two different ports, one for HTTP traffic and one for gRPC traffic, which is why we port forward both. + +From here, you should be able to run through the :ref:`Getting Started ` +examples again. Save a backup copy of your existing configuration if you have one +and generate a new config with ``flytectl``. + +.. prompt:: bash $ + + mv ~/.flyte/config.yaml ~/.flyte/bak.config.yaml + flytectl config init --host localhost:8088 + +This will produce a file like: + +.. code-block:: yaml + :caption: ``~/.flyte/config.yaml`` + + admin: + # For GRPC endpoints you might want to use dns:///flyte.myexample.com + endpoint: dns:///localhost:8088 + authType: Pkce + insecure: true + logger: + show-source: true + level: 0 + +Test Workflow +------------- + +You can test a workflow by cloning the ``flytesnacks`` repo and running the +hello world example: + +.. prompt:: bash $ + + git clone https://github.com/flyteorg/flytesnacks + cd flytesnacks/cookbook + pyflyte run --remote core/flyte_basics/hello_world.py my_wf + +*********************************** +Flyte in on-premises infrastructure +*********************************** + +Sometimes, it's also helpful to be able to set up a Flyte environment in an on-premises Kubernetes environment or even on a laptop for testing and development purposes. +Check out `this community-maintained tutorial `__ to learn how to setup the required dependencies and deploy the `flyte-binary` chart to a local Kubernetes cluster. + + +************* +What's Next? +************* + +Congratulations ⭐️! Now that you have a Flyte cluster up and running on the cloud, +you can productionize it by following the :ref:`deployment-deployment-cloud-production` +guide. diff --git a/docs/deployment/deployment/index.rst b/docs/deployment/deployment/index.rst new file mode 100644 index 0000000000..eb06d0a6c0 --- /dev/null +++ b/docs/deployment/deployment/index.rst @@ -0,0 +1,159 @@ +.. _deployment-deployment: + +################### +Deployment Paths +################### + +The articles in this section will guide a new Flyte administrator through deploying Flyte. + +The most complex parts of a Flyte deployment are authentication, ingress, DNS, and SSL support. Due to the complexity +introduced by these components, we recommend deploying Flyte without these at first and relying on K8s port forwarding +to test your Flyte cluster. After the base deployment is tested, these additional features can be turned on more +seamlessly. + +******************************** +Components of a Flyte Deployment +******************************** + +.. important:: + + We recommend working with your infrastructure team to set up the cloud service requirements below. + +Relational Database +=================== + +Two of Flyte's components, :ref:`FlyteAdmin ` and :ref:`DataCatalog `, rely on +PostgreSQL to store persistent records. In the sandbox deployment, a containerized version of Postgres is included but +for a proper Flyte installation, we recommend one of the cloud provided databases. + +.. note:: + + We recommend the following services, depending on your cloud platform of choice: + + - **AWS**: `RDS `__ + - **GCP**: `Cloud SQL `__ + - **Azure**: `PostgreSQL `__ + +Production Grade Object Store +============================= + +Core Flyte components such as :ref:`FlyteAdmin `, :ref:`FlytePropeller `, +:ref:`DataCatalog `, and user runtime containers rely on an object store to hold files. The sandbox +deployment comes with a containerized `Minio `__, which offers AWS S3 compatibility. + +.. note:: + + We recommend swapping this out for a production-grade object store, depending on your cloud platform of choice: + + - **AWS**: `S3 `__ + - **GCP**: `GCS `__ + - **Azure**: `Azure Blob Storage `__ + +************************ +Flyte Deployment Paths +************************ + +There are three different paths for deploying a Flyte cluster: + +.. list-table:: + :header-rows: 1 + :widths: 25, 65, 20 + + * - Deployment Path + - Description + - Production-grade? + * - :ref:`Sandbox ` + - This uses portable replacements for the relational database and blob store. + It's good for testing out and experimenting with Flyte. + - ❌ + * - :ref:`Single Cluster ` + - This bundles Flyte as one executable. It runs on a single K8s cluster and + supports all of Flyte's extensions and plugins. Once the simple deployment + is established, you can follow steps to :ref:`productionize it `. + - ✅ + * - :ref:`Multiple Clusters ` + - For large-scale deployments that require multiple K8s clusters. Flyte's control + plane (:ref:`FlyteAdmin `, :ref:`FlyteConsole `, and :ref:`DataCatalog `) + is separated from Flyte's execution engine, :ref:`FlytePropeller `, which runs + typically once per compute cluster. + - ✅ + +.. important:: + + We recommend the **Single Cluster** option for a capable though not massively scalable cluster. + + This option is appropriate if all your compute can `fit on one EKS cluster `__ . + As of this writing, a single Flyte cluster can handle more than 13,000 nodes. + + Regardless of using single or multiple Kubernetes clusters for Flyte, note that ``FlytePropeller`` -the main data plane component- can be scaled out as well by using ``sharding`` if scale demands require it. + See `Automatic scale-out `__ to learn more about the sharding mechanism. + + + +Helm +==== + +Flyte uses `Helm `__ as the K8s release packaging solution, though you may still see some old +`Kustomize `__ artifacts in the `flyte `__ repo. The core Flyte +team maintains Helm charts that correspond with the latter two deployment paths. + +.. note:: + + Technically there is a Helm chart for the sandbox environment as well, but it's been tested only with the Dockerized + K3s bundled container. + +.. dropdown:: ``flyte-binary``: chart for the **Single Cluster** option. + :title: text-muted + + .. literalinclude:: ../../../charts/flyte-binary/Chart.yaml + :language: yaml + :caption: charts/flyte-binary/Chart.yaml + +.. dropdown:: ``flyte-core``: chart for the **Multiple Cluster** option. + :title: text-muted + + .. literalinclude:: ../../../charts/flyte-core/Chart.yaml + :language: yaml + :caption: charts/flyte-core/Chart.yaml + +.. dropdown:: ``flyte-deps``: chart that installs additional useful dependencies alongside Flyte. + :title: text-muted + + .. literalinclude:: ../../../charts/flyte-deps/Chart.yaml + :language: yaml + :caption: charts/flyte-deps/Chart.yaml + +.. dropdown:: ``flyte``: chart that depends on ``flyte-core``, installing additional dependencies to Flyte deployment. + :title: text-muted + + .. literalinclude:: ../../../charts/flyte/Chart.yaml + :language: yaml + :caption: charts/flyte/Chart.yaml + +************************************** +Deployment Tips and Tricks +************************************** + +Due to the many choices and constraints that you may face in your organization, the specific steps for deploying Flyte +can vary significantly. For example, which cloud platform to use is typically a big fork in the road for many, and there +are many choices to make in terms of Ingress controllers, auth providers, and versions of different dependent libraries that +may interact with other parts of your stack. + +Considering the above, we recommend checking out the `"Flyte The Hard Way" `__ set of community-maintained tutorials that can guide you through the process of preparing the infrastructure and +deploying Flyte. + +In addition to searching and posting on the `#flyte-deployment Slack channel `__, +we have a `Github Discussion `__ +section dedicated to deploying Flyte. Feel free to submit any hints you've found helpful as a discussion, ask questions, +or simply document what worked or what didn't work for you. + + +.. toctree:: + :maxdepth: 1 + :name: deployment options toc + :hidden: + + sandbox + cloud_simple + cloud_production + multicluster diff --git a/docs/deployment/deployment/multicluster.rst b/docs/deployment/deployment/multicluster.rst new file mode 100644 index 0000000000..e8c6b84f13 --- /dev/null +++ b/docs/deployment/deployment/multicluster.rst @@ -0,0 +1,661 @@ +.. _deployment-deployment-multicluster: + +###################################### +Multiple Kubernetes Cluster Deployment +###################################### + +.. tags:: Kubernetes, Infrastructure, Advanced + +.. note:: + + The multicluster deployment described in this section, assumes you have deployed + the ``flyte-core`` Helm chart, which runs the individual Flyte components separately. + This is needed because in a multicluster setup, the execution engine is + deployed to multiple K8s clusters; it won't work with the ``flyte-binary`` + Helm chart, since it deploys all Flyte services as one single binary. + +Scaling Beyond Kubernetes +------------------------- + +.. tip:: + + As described in the `Architecture Overview `_, + the Flyte ``Control Plane`` sends workflows off to the ``Data Plane`` for + execution. The data plane fulfills these workflows by launching pods in + Kubernetes. + + +.. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/common/flyte-multicluster-arch-v2.png + +The case for multiple Kubernetes clusters may arise due to security constraints, +cost effectiveness or a need to scale out computing resources. + +To address this, you can deploy Flyte's data plane to multiple Kubernetes clusters. +The control plane (FlyteAdmin) can be configured to submit workflows to +these individual data planes. Additionally, Flyte provides the mechanisms for +administrators to retain control on the workflow placement logic while enabling +users to reap the benefits using simple abstractions like ``projects`` and ``domains``. + +Prerequisites +************* + +To make sure that your multicluster deployment is able to scale and process +requests successfully, the following environment-specific requirements should be met: + +.. tabbed:: AWS + + 1. An IAM Policy that defines the permissions needed for Flyte. A minimum set of permissions include: + + .. code-block:: json + + "Action": [ + "s3:DeleteObject*", + "s3:GetObject*", + "s3:ListBucket", + "s3:PutObject*" + ], + "Resource": [ + "arn:aws:s3:::*", + "arn:aws:s3:::*/*" + ], + + + 2. Two IAM Roles configured: one for the control plane components, and another for the data plane where the worker Pods and ``flytepropeller`` run. + + .. note:: + + Using the guidance from this document, make sure to follow your organization's policies to configure IAM resources. + + 3. An OIDC Provider associated with each of your EKS clusters. You can use the following command to create and connect the Provider: + + .. prompt:: bash + + eksctl utils associate-iam-oidc-provider --cluster --approve + + 4. An IAM Trust Relationship that associates each EKS cluster type (control plane or data plane) with the Service Account(s) and namespaces + where the different elements of the system will run. + + Follow the steps in this section to complete the requirements indicated above: + + **Control plane role** + + 1. Use the following command to simplify the process of both creating a role and configuring an initial Trust Relationship: + + .. prompt:: bash + + eksctl create iamserviceaccount --cluster= --name=flyteadmin --role-only --role-name=flyte-controlplane-role --attach-policy-arn --approve --region --namespace flyte + + 2. Go to the **IAM** section in your **AWS Management Console** and select the role that was just created + 3. Go to the **Trust Relationships** tab and **Edit the Trust Policy** + 4. Add the ``datacatalog`` Service Account to the ``sub`` section + + .. note:: + + When caching is enabled, the ``datacatalog`` service store hashes of workflow inputs alongside with outputs on blob storage. Learn more `here `__. + + Example configuration: + + .. code-block:: json + + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "oidc.eks..amazonaws.com/id/:aud": "sts.amazonaws.com", + "oidc.eks..amazonaws.com/id/:sub": [ + "system:serviceaccount:flyte:flyteadmin", + "system:serviceaccount:flyte:datacatalog" + ] + } + } + } + ] + } + + **Data plane role** + + 1. Create the role and Trust Relationship: + + .. prompt:: bash + + eksctl create iamserviceaccount --cluster= --name=flytepropeller --role-only --role-name=flyte-dataplane-role --attach-policy-arn --approve --region --namespace flyte + + 2. Edit the **Trust Relationship** of the data plane role + + .. note:: + + By default, every Pod created for Task execution, uses the ``default`` Service Account on their respective namespace. In your cluster, you'll have as many + namespaces as ``project`` and ``domain`` combinations you may have. Hence, it might be useful to use a ``StringLike`` condition and to use a wildcard for the namespace name in the Trust Policy + + 3. Add the ``default`` Service Account: + + + Example configuration for one data plane cluster: + + .. code-block:: json + + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringLike": { + "oidc.eks..amazonaws.com/id/.:aud": "sts.amazonaws.com", + "oidc.eks..amazonaws.com/id/.:sub": [ + "system:serviceaccount:flyte:flytepropeller", + "system:serviceaccount:*:default" + ] + } + } + } + + .. note:: + + To further refine the Trust Relationship, consider using a ``StringEquals`` condition and adding the ``default`` Service Account only for the ``project``-``domain`` + namespaces where Flyte tasks will run, instead of using a wildcard. + +.. _dataplane-deployment: + +Data Plane Deployment +********************* + +This guide assumes that you have two Kubernetes clusters and that you can access +them all with ``kubectl``. + +Let's call these clusters ``dataplane1`` and ``dataplane2``. In this section, you'll prepare +the first cluster only. + +1. Add the ``flyteorg`` Helm repo: + +.. prompt:: bash + + helm repo add flyteorg https://flyteorg.github.io/flyte + helm repo update + # Get flyte-core helm chart + helm fetch --untar --untardir . flyteorg/flyte-core + cd flyte-core + +2. Open the ``values-dataplane.yaml`` file and add the following contents: + + .. code-block:: yaml + + configmap: + admin: + admin: + endpoint: :443 #indicate the URL you're using to connect to Flyte + insecure: false #enables secure communication over SSL. Requires a signed certificate + catalog: + catalog-cache: + endpoint: :443 + insecure: false + +.. note:: + + This step is needed so the ``flytepropeller`` instance in the data plane cluster is able to send notifications + back to the ``flyteadmin`` service in the control plane. The ``catalog`` service runs in the control plane and is used when caching is enabled. + +3. Install Flyte data plane Helm chart: + +.. note:: + + Use the same ``values-eks.yaml`` or ``values-gcp.yaml`` file you used to deploy the control plane. + +.. tabbed:: AWS + + .. code-block:: + + helm install flyte-core-data flyteorg/flyte-core -n flyte \ + --values values-eks.yaml --values values-dataplane.yaml \ + --create-namespace + +.. tabbed:: GCP + + .. code-block:: + + helm install flyte-core-data -n flyte flyteorg/flyte-core \ + --values values-gcp.yaml \ + --values values-dataplane.yaml \ + --create-namespace flyte + +.. _control-plane-deployment: + +Control Plane configuration +********************************* + +For ``flyteadmin`` to access and create Kubernetes resources in one or more +Flyte data plane clusters, it needs credentials to each cluster. +Flyte makes use of Kubernetes Service Accounts to enable every control plane cluster to perform +authenticated requests to the data plane Kubernetes API Server. +The default behaviour is that the Helm chart creates a `ServiceAccount `_ +in each data plane cluster. +In order to verify requests, the Kubernetes API Server expects a `signed bearer token `__ +attached to the Service Account. As of Kubernetes 1.24 and above, the bearer token has to be generated manually. + + +1. Use the following manifest to create a long-lived bearer token for the ``flyteadmin`` Service Account in your data plane cluster: + + .. prompt:: bash + + kubectl apply -f - < + +5. Obtain the corresponding certificate: + +.. prompt:: bash $ + + kubectl get secret -n flyte dataplane1-token \ + -o jsonpath='{.data.ca\.crt}' | pbcopy + +6. Add another entry on your ``secrets.yaml`` file for the certificate: + +.. code-block:: yaml + :caption: secrets.yaml + + apiVersion: v1 + kind: Secret + metadata: + name: cluster-credentials + namespace: flyte + type: Opaque + data: + dataplane_1_token: + dataplane_1_cacert: + +7. Connect to your control plane cluster and create the ``cluster-credentials`` secret: + +.. prompt:: bash $ + + kubectl apply -f secrets.yaml + +8. Create a file named ``values-override.yaml`` and add the following config to it: + +.. code-block:: yaml + :caption: values-override.yaml + + flyteadmin: + additionalVolumes: + - name: cluster-credentials + secret: + secretName: cluster-credentials + additionalVolumeMounts: + - name: cluster-credentials + mountPath: /var/run/credentials + initContainerClusterSyncAdditionalVolumeMounts: + - name: cluster-credentials + mountPath: /etc/credentials + configmap: + clusters: + labelClusterMap: + label1: + - id: dataplane_1 + weight: 1 + clusterConfigs: + - name: "dataplane_1" + endpoint: https://:443 + enabled: true + auth: + type: "file_path" + tokenPath: "/var/run/credentials/dataplane_1_token" + certPath: "/var/run/credentials/dataplane_1_cacert" + +.. note:: + + Typically, you can obtain your Kubernetes API endpoint URL using the following command: + + .. prompt:: bash $ + + kubectl cluster-info + +In this configuration, ``label1`` and ``label2`` are just labels that we will use later in the process +to configure mappings that enable workflow executions matching those labels, to be scheduled +on one or multiple clusters depending on the weight (e.g. ``label1`` on ``dataplane_1``). The ``weight`` is the +priority of a specific cluster, relative to the other clusters under the ``labelClusterMap`` entry. The total sum of weights under a particular +label has to be 1. + +9. Add the ``flyte-dataplane-role`` IAM Role as the ``defaultIamRole`` in your ``values-eks.yaml`` file. `See section here `__ + +10. Update the control plane Helm release: + +.. note:: + This step will disable ``flytepropeller`` in the control plane cluster, leaving no possibility of running workflows there. If you require + the control plane to run workflows, edit the ``values-controlplane.yaml`` file and set ``flytepropeller.enabled`` to ``true``. Then, perform the ``helm upgrade`` operation and complete the steps in :ref:`this section ` to configure it + as a dataplane cluster. + +.. tabbed:: AWS + + .. code-block:: + + helm upgrade flyte-core flyteorg/flyte-core \ + --values values-eks-controlplane.yaml --values values-override.yaml \ + --values values-eks.yaml -n flyte + +.. tabbed:: GCP + + .. code-block:: + + helm upgrade flyte -n flyte flyteorg/flyte-core values.yaml \ + --values values-gcp.yaml \ + --values values-controlplane.yaml \ + --values values-override.yaml + +11. Verify that all Pods in the ``flyte`` namespace are ``Running``: + +Example output: + +.. prompt:: bash $ + + kubectl get pods -n flyte + NAME READY STATUS RESTARTS AGE + datacatalog-86f6b9bf64-bp2cj 1/1 Running 0 23h + datacatalog-86f6b9bf64-fjzcp 1/1 Running 0 23h + flyteadmin-84f666b6f5-7g65j 1/1 Running 0 23h + flyteadmin-84f666b6f5-sqfwv 1/1 Running 0 23h + flyteconsole-cdcb48b56-5qzlb 1/1 Running 0 23h + flyteconsole-cdcb48b56-zj75l 1/1 Running 0 23h + flytescheduler-947ccbd6-r8kg5 1/1 Running 0 23h + syncresources-6d8794bbcb-754wn 1/1 Running 0 23h + + +Configure Execution Cluster Labels +********************************** + +The next step is to configure project-domain or workflow labels to schedule on a specific +Kubernetes cluster. + +.. tabbed:: Configure Project & Domain + + 1. Create an ``ecl.yaml`` file with the following contents: + + .. code-block:: yaml + + domain: development + project: project1 + value: label1 + + .. note:: + + Change ``domain`` and ``project`` according to your environment. The ``value`` has + to match with the entry under ``labelClusterMap`` in the ``values-override.yaml`` file. + + 2. Repeat step 1 for every project-domain mapping you need to configure, creating a YAML file for each one. + + 3. Update the execution cluster label of the project and domain: + + .. prompt:: bash $ + + flytectl update execution-cluster-label --attrFile ecl.yaml + + Example output: + + .. prompt:: bash $ + + Updated attributes from team1 project and domain development + + + 4. Execute a workflow indicating project and domain: + + .. prompt:: bash $ + + pyflyte run --remote --project team1 --domain development example.py training_workflow \  ✔ ╱ docs-development-env  + --hyperparameters '{"C": 0.1}' + +.. tabbed:: Configure a Specific Workflow mapping + + 1. Create a ``workflow-ecl.yaml`` file with the following example contents: + + .. code-block:: yaml + + domain: development + project: project1 + workflow: example.training_workflow + value: project1 + + 2. Update execution cluster label of the project and domain + + .. prompt:: bash $ + + flytectl update execution-cluster-label \ + -p project1 -d development \ + example.training_workflow \ + --attrFile workflow-ecl.yaml + + 3. Execute a workflow indicating project and domain: + + .. prompt:: bash $ + + pyflyte run --remote --project team1 --domain development example.py training_workflow \  ✔ ╱ docs-development-env  + --hyperparameters '{"C": 0.1}' + +Congratulations 🎉! With this, the execution of workflows belonging to a specific +project-domain or a single specific workflow will be scheduled on the target label +cluster. + +Day 2 Operations +---------------- + +Add another Kubernetes cluster +****************************** + +Find in this section the necessary steps to scale out your deployment by adding one Kubernetes cluster. +The process can be repeated for additional clusters. + +.. tabbed:: AWS + + + + 1. Create the new cluster: + + .. prompt:: bash $ + + eksctl create cluster --name flyte-dataplane-2 --region --version 1.25 --vpc-private-subnets , --without-nodegroup + + .. note:: + + This is only one of multiple ways to provision an EKS cluster. Follow your organization's policies to complete this step. + + + 2. Add a nodegroup to the cluster. Typically ``t3.xlarge`` instances provide enough resources to get started. Follow your organization's policies in this regard. + + 4. Create an OIDC Provider for the new cluster: + + .. prompt:: bash $ + + eksctl utils associate-iam-oidc-provider --cluster flyte-dataplane-2 --region --approve + + 5. Take note of the OIDC Provider ID: + + .. prompt:: bash $ + + aws eks describe-cluster --region --name flyte-dataplane-2 --query "cluster.identity.oidc.issuer" --output text + + 6. Go to the **IAM** section in the **AWS Management Console** and edit the **Trust Policy** of the ``flyte-dataplane-role`` + 7. Add a new ``Principal`` with the new cluster's OIDC Provider ID. Include the ``Action`` and ``Conditions`` section: + + .. code-block:: json + + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringLike": { + "oidc.eks..amazonaws.com/id/:aud": "sts.amazonaws.com", + + "oidc.eks..amazonaws.com/id/:sub": [ + "system:serviceaccount:flyte:flytepropeller", + "system:serviceaccount:*:default" + ] + } + } + }, + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringLike": { + "oidc.eks..amazonaws.com/id/:aud": "sts.amazonaws.com", + "oidc.eks..amazonaws.com/id/:sub": [ + "system:serviceaccount:flyte:flytepropeller", + "system:serviceaccount:*:default" + ] + } + } + } + ] + } + + + + 7. Install the data plane Helm chart following the steps in the **Data plane deployment** section. See :ref:`section `. + 8. Follow steps 1-3 in the **control plane configuration** section (see :ref:`section `) to generate and populate a new section in your ``secrets.yaml`` file + + Example: + + .. code-block:: yaml + + apiVersion: v1 + kind: Secret + metadata: + name: cluster-credentials + namespace: flyte + type: Opaque + data: + dataplane_1_token: + dataplane_1_cacert: + dataplane_2_token: + dataplane_2_cacert: + + 9. Connect to the control plane cluster and update the ``cluster-credentials`` Secret: + + .. prompt:: bash $ + + kubect apply -f secrets.yaml + + 10. Go to your ``values-override.yaml`` file and add the information of the new cluster. Adding a new label is not entirely needed. + Nevertheless, in the following example a new label is created to illustrate Flyte's capability to schedule workloads on different clusters + in response to user-defined mappings of ``project``, ``domain`` and ``label``:abbr: + + .. code-block:: yaml + + ... #all the above content remains the same + configmap: + clusters: + labelClusterMap: + label1: + - id: dataplane_1 + weight: 1 + label2: + - id: dataplane_2 + weight: 1 + clusterConfigs: + - name: "dataplane_1" + endpoint: https://.com:443 + enabled: true + auth: + type: "file_path" + tokenPath: "/var/run/credentials/dataplane_1_token" + certPath: "/var/run/credentials/dataplane_1_cacert" + - name: "dataplane_2" + endpoint: https://:443 + enabled: true + auth: + type: "file_path" + tokenPath: "/var/run/credentials/dataplane_2_token" + certPath: "/var/run/credentials/dataplane_2_cacert" + + 11. Update the Helm release in the control plane cluster: + + .. prompt:: bash $ + + helm upgrade flyte-core-control flyteorg/flyte-core -n flyte --values values-controlplane.yaml --values values-eks.yaml --values values-override.yaml + + 12. Create a new execution cluster labels file with the following sample content: + + .. code-block:: yaml + + domain: production + project: team1 + value: label2 + + 13. Update the cluster execution labels for the project: + + .. prompt:: bash $ + + flytectl update execution-cluster-label --attrFile ecl-production.yaml + + 14. Finally, submit a workflow execution that matches the label of the new cluster: + + .. prompt:: bash $ + + pyflyte run --remote --project team1 --domain production example.py training_workflow \ + --hyperparameters '{"C": 0.1}' + + 15. A successful execution should be visible on the UI, confirming it ran in the new cluster: + + .. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/common/multicluster-execution.png \ No newline at end of file diff --git a/docs/deployment/deployment/sandbox.rst b/docs/deployment/deployment/sandbox.rst new file mode 100644 index 0000000000..ebcef880ac --- /dev/null +++ b/docs/deployment/deployment/sandbox.rst @@ -0,0 +1,114 @@ +.. _deployment-deployment-sandbox: + +######################### +Sandbox Deployment +######################### + +.. tags:: Kubernetes, Infrastructure, Basic + +A sandbox deployment of Flyte bundles together portable versions of Flyte's +dependencies such as a relational database and durable object store. + +For the blob store requirements, Flyte Sandbox uses `Minio `__, +which offers an S3 compatible interface, and for Postgres, it uses the stock +Postgres Docker image and Helm chart. + +.. important:: + + The sandbox deployment is not suitable for production environments. For instructions on how to create a + production-ready Flyte deployment, checkout the :ref:`Deployment Paths ` guide. + +******************************************* +Flyte Sandbox as a Single Docker Container +******************************************* + +Flyte provides a way for creating a Flyte cluster as a self-contained Docker image. This is mini-replica of an +entire Flyte deployment, without the scalability and with minimal extensions. + +The Flyte Sandbox can be run on any environment that supports containers and makes it extremely easy for users of Flyte +to try out the platform and get a feel for the user experience, all without having to understand Kubernetes or dabble +with configuration. + +.. note:: + + The Flyte single container sandbox is also used by the team to run continuous integration tests and used by the + :ref:`cookbook:userguide`, :ref:`cookbook:tutorials` and :ref:`cookbook:integrations` documentation. + +Requirements +============ + +- Install `kubectl `__. +- Install `docker `__ or any other OCI-compatible tool, like Podman or LXD. +- Install `flytectl `__, the official CLI for Flyte. + +While Flyte can run any OCI-compatible task image using the default Kubernetes container runtime (``containerd``), the Flyte +core maintainers typically use Docker. Note that the ``flytectl demo`` command does rely on Docker APIs, but as this +demo environment is just one self-contained image, you can also run the image directly using another run time. + +Within the single container environment, a mini Kubernetes cluster is installed using `k3s `__. K3s +uses an in-container Docker daemon, run using `docker-in-docker configuration `__ +to orchestrate user containers. + +Start the Sandbox +================== + +To spin up a Flyte Sandbox, run: + +.. prompt:: bash $ + + flytectl demo start + +This command runs a Docker container, which itself comes with a Docker registry +on ``localhost:30000`` so you can build images outside of the docker-in-docker +container by tagging your containers with ``localhost:30000/imgname:tag`` and +pushing the image. + +The local Postgres installation is also available on port ``30001`` for users +who wish to dig deeper into the storage layer. + +.. div:: shadow p-3 mb-8 rounded + + **Expected Output:** + + .. code-block:: + + 👨‍💻 Flyte is ready! Flyte UI is available at http://localhost:30080/console 🚀 🚀 🎉 + ❇️ Run the following command to export sandbox environment variables for accessing flytectl + export FLYTECTL_CONFIG=~/.flyte/config-sandbox.yaml + 🐋 Flyte sandbox ships with a Docker registry. Tag and push custom workflow images to localhost:30000 + 📂 The Minio API is hosted on localhost:30002. Use http://localhost:30080/minio/login for Minio console + + +Configuration +______________ + +The ``config-sandbox.yaml`` file contains configuration for **FlyteAdmin**, +which is the Flyte cluster backend component that processes all client requests +such as workflow executions. The default values are enough to let you connect and use Flyte: + + +.. code-block:: yaml + + admin: + # For GRPC endpoints you might want to use dns:///flyte.myexample.com + endpoint: localhost:30080 + authType: Pkce + insecure: true + console: + endpoint: http://localhost:30080 + logger: + show-source: true + level: 0 + +.. note:: + + You can also create your own config file with `flytectl config init`, which + will create a config file at `~/.flyte/config.yaml`. + + Learn more about the configuration settings in the + {ref}`Deployment Guide ` + + + +Now that you have the sandbox cluster running, you can now go to the :ref:`User Guide ` or +:ref:`Tutorials ` to run tasks and workflows written in ``flytekit``, the Python SDK for Flyte. diff --git a/docs/deployment/index.md b/docs/deployment/index.md new file mode 100644 index 0000000000..fa45ddce90 --- /dev/null +++ b/docs/deployment/index.md @@ -0,0 +1,26 @@ +(deployment)= + +# Deployment Guide + +These *Deployment Guides* are primarily for platform and devops engineers to learn how to deploy and administer Flyte. + +The sections below walk through how to create a Flyte cluster and cover topics related to enabling and configuring +plugins, authentication, performance tuning, and maintaining Flyte as a production-grade service. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {ref}`🛣 Deployment Paths ` + - Walkthroughs for deploying Flyte, from the most basic to a fully-featured, multi-cluster production system. +* - {ref}`🔌 Plugin Setup ` + - Enable backend plugins to extend Flyte's capabilities, such as hooks for K8s, AWS, GCP, and Web API services. +* - {ref}`🤖 Agent Setup ` + - Enable backend plugins to extend Flyte's capabilities, such as hooks for K8s, AWS, GCP, and Web API services. +* - {ref}`🎛 Cluster Configuration ` + - How to configure the various components of your cluster. +* - {ref}`📖 Configuration Reference ` + - Reference docs for configuration settings for Flyte's backend services. +* - {ref}`🔒 Security Overview ` + - Read for comments on security in Flyte. +``` diff --git a/docs/deployment/plugins/aws/athena.rst b/docs/deployment/plugins/aws/athena.rst new file mode 100644 index 0000000000..34edafc4bd --- /dev/null +++ b/docs/deployment/plugins/aws/athena.rst @@ -0,0 +1,87 @@ +.. _deployment-plugin-setup-aws-athena: + +Athena Plugin +============= + +This guide provides an overview of setting up Athena in your Flyte deployment. + +.. note:: + Please note that the Athena plugin requires a Flyte deployment in the AWS cloud; it won't work with demo/GCP/Azure. + +Set up the AWS Flyte cluster +---------------------------- + +1. Ensure you have a functional Flyte cluster up and running in `AWS `__ +2. Verify that you possess the correct ``kubeconfig`` and have selected the appropriate Kubernetes context +3. Double-check that your ``~/.flyte/config.yaml`` file contains the correct Flytectl configuration + +Specify plugin configuration +---------------------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + Edit the relevant YAML file to specify the plugin. + + .. code-block:: yaml + :emphasize-lines: 7,11 + + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - athena + default-for-task-types: + - container: container + - container_array: k8s-array + - athena: athena + + .. group-tab:: Flyte core + + Create a file named ``values-override.yaml`` and include the following configuration: + + .. code-block:: yaml + + configmap: + enabled_plugins: + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - athena + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + athena: athena + +Ensure that the propeller has the correct service account for Athena. + +Upgrade the Flyte Helm release +------------------------------ + +.. tabs:: + + .. group-tab:: Flyte binary + + .. code-block:: bash + + helm upgrade flyteorg/flyte-binary -n --values + + Replace ```` with the name of your release (e.g., ``flyte-backend``), + ```` with the name of your namespace (e.g., ``flyte``), + and ```` with the name of your YAML file. + + .. group-tab:: Flyte core + + .. code-block:: bash + + helm upgrade flyte/flyte-core -n --values values-override.yaml + + Replace ```` with the name of your release (e.g., ``flyte``) + and ```` with the name of your namespace (e.g., ``flyte``). diff --git a/docs/deployment/plugins/aws/batch.rst b/docs/deployment/plugins/aws/batch.rst new file mode 100644 index 0000000000..ba6d069b74 --- /dev/null +++ b/docs/deployment/plugins/aws/batch.rst @@ -0,0 +1,165 @@ +.. _deployment-plugin-setup-aws-array: + +AWS Batch +========= + +This setup document applies to both :py:func:`map tasks ` +and single tasks running on AWS Batch. + +.. note:: + + For single [non-map] task use, please take note of + the additional code when updating the flytepropeller config. + +AWS Batch simplifies the process for developers, scientists and engineers to run +hundreds of thousands of batch computing jobs on AWS. + +Flyte abstracts away the complexity of integrating AWS Batch into users' workflows, +taking care of packaging inputs, reading outputs, scheduling map tasks and +optimizing AWS Batch job queues for load distribution and priority coordination. + +Set up AWS Batch +---------------- + +Follow the guide `Running batch jobs +at scale for less `__. + +By the end of this step, your AWS Account should have a configured compute environment +and one or more AWS Batch Job Queues. + +Modify users' AWS IAM role trust policy document +------------------------------------------------ + +Follow the guide `AWS Batch Execution +IAM role `__. + +When running workflows in Flyte, users can specify a Kubernetes service account and/or an IAM Role to run as. +For AWS Batch, an IAM Role must be specified. For each of these IAM Roles, modify the trust policy +to allow elastic container service (ECS) to assume the role. + +Modify system's AWS IAM role policies +------------------------------------- + +Follow the guide `Granting a user permissions to pass a +role to an AWS service `__. + +The best practice for granting permissions to Flyte components is by utilizing OIDC, +as described in the +`OIDC documentation `__. +This approach entails assigning an IAM Role to each service account being used. +To proceed, identify the IAM Role associated with the flytepropeller's Kubernetes service account, +and subsequently, modify the policy document to enable the role to pass other roles to AWS Batch. + +Update FlyteAdmin configuration +------------------------------- + +FlyteAdmin must be informed of all the AWS Batch job queues +and how the system should distribute the load among them. +The simplest setup is as follows: + +.. code-block:: yaml + + flyteadmin: + roleNameKey: "eks.amazonaws.com/role-arn" + queues: + # A list of items, one per AWS Batch Job Queue. + executionQueues: + # The name of the job queue from AWS Batch + - dynamic: "tutorial" + # A list of tags/attributes that can be used to match workflows to this queue. + attributes: + - default + # A list of configs to match project and/or domain and/or workflows to job queues using tags. + workflowConfigs: + # An empty rule to match any workflow to the queue tagged as "default" + - tags: + - default + +If you are using Helm, you can add this block under the ``configMaps.adminServer`` section, +as shown `here `__. + +For a more complex matching configuration, the example below defines three different queues +with distinct attributes and matching logic based on project/domain/workflowName. + +.. code-block:: yaml + + queues: + executionQueues: + - dynamic: "gpu_dynamic" + attributes: + - gpu + - dynamic: "critical" + attributes: + - critical + - dynamic: "default" + attributes: + - default + workflowConfigs: + - project: "my_queue_1" + domain: "production" + workflowName: "my_workflow_1" + tags: + - critical + - project: "production" + workflowName: "my_workflow_2" + tags: + - gpu + - project: "my_queue_3" + domain: "production" + workflowName: "my_workflow_3" + tags: + - critical + - tags: + - default + +These settings can also be dynamically altered through ``flytectl`` (or FlyteAdmin API). +Learn about the :ref:`core concept here `. +For guidance on how to dynamically update these configurations, refer to the :ref:`Flytectl docs `. + +Update FlytePropeller's configuration +------------------------------------- + +The AWS Array Plugin requires specific configurations to ensure proper communication with the AWS Batch Service. + +These configurations reside within FlytePropeller's configMap. Modify the config in the relevant YAML file to set the following keys: + +.. code-block:: yaml + + plugins: + aws: + batch: + # Must match that set in flyteAdmin's configMap flyteadmin.roleNameKey + roleAnnotationKey: eks.amazonaws.com/role-arn + # Must match the desired region to launch these tasks. + region: us-east-2 + tasks: + task-plugins: + enabled-plugins: + # Enable aws_array task plugin. + - aws_array + default-for-task-types: + # Set it as the default handler for array/map tasks. + container_array: aws_array + # Make sure to add this line to enable single (non-map) AWS Batch tasks + aws-batch: aws_array + +.. note:: + + To register the `map task + `__ on Flyte, + use the command ``pyflyte register ``. + Launch the execution through the FlyteConsole by selecting the appropriate ``IAM Role`` and entering the full + ``AWS Arn`` of an IAM Role configured according to the above guide. + + Once the task starts executing, you'll find a link for the AWS Array Job in the log links section of the Flyte Console. + As individual jobs start getting scheduled, links to their respective CloudWatch log streams will also appear in the UI. + + .. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/deployment/aws_plugin_setup/map_task_success.png + :alt: A screenshot of Flyte Console displaying log links for a successful array job. + + *A screenshot of Flyte Console displaying log links for a successful array job.* + + .. image:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/deployment/aws_plugin_setup/map_task_failure.png + :alt: A screenshot of Flyte Console displaying log links for a failed array job. + + *A screenshot of Flyte Console displaying log links for a failed array job.* diff --git a/docs/deployment/plugins/aws/index.md b/docs/deployment/plugins/aws/index.md new file mode 100644 index 0000000000..5988ebac83 --- /dev/null +++ b/docs/deployment/plugins/aws/index.md @@ -0,0 +1,31 @@ +(deployment-plugin-setup-aws)= + +# Configure AWS Plugins + +```{eval-rst} +.. tags:: AWS, Integration, MachineLearning, Data, Advanced +``` + +Discover the process of setting up AWS plugins for Flyte. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {ref}`AWS Batch ` + - Guide to setting up the AWS Batch plugin. +* - {ref}`AWS Athena ` + - Guide to setting up the AWS Athena plugin. +* - {ref}`AWS Sagemaker ` + - Guide to setting up the AWS Sagemaker plugin. +``` + +```{toctree} +:maxdepth: 1 +:name: AWS plugin setup +:hidden: + +batch +athena +sagemaker +``` diff --git a/docs/deployment/plugins/aws/sagemaker.rst b/docs/deployment/plugins/aws/sagemaker.rst new file mode 100644 index 0000000000..6411ee6c2b --- /dev/null +++ b/docs/deployment/plugins/aws/sagemaker.rst @@ -0,0 +1,98 @@ +.. _deployment-plugin-setup-aws-sagemaker: + +Sagemaker Plugin Setup +---------------------- + +This guide gives an overview of how to set up Sagemaker in your Flyte deployment. + +.. note:: + + The Sagemaker plugin needs Flyte deployment in AWS cloud; sandbox/GCP/Azure + won't work. + +Setup the AWS Flyte cluster +=========================== + +.. tabs:: + + .. tab:: AWS cluster setup + + * Make sure you have up and running flyte cluster in `AWS `__ + * You have your `AWS role set up correctly for SageMaker `_ + * `AWS SageMaker k8s operator `_ is installed in your k8s cluster + * Make sure you have correct kubeconfig and selected the correct kubernetes context + * make sure you have the correct FlyteCTL config at ~/.flyte/config.yaml + +Specify Plugin Configuration +====================================== + +Create a file named ``values-override.yaml`` and add the following config to it. +Please make sure that the propeller has the correct service account for Sagemaker. + +.. code-block:: yaml + + configmap: + enabled_plugins: + # -- Tasks specific configuration [structure](https://pkg.go.dev/github.com/flyteorg/flytepropeller/pkg/controller/nodes/task/config#GetConfig) + tasks: + # -- Plugins configuration, [structure](https://pkg.go.dev/github.com/flyteorg/flytepropeller/pkg/controller/nodes/task/config#TaskPluginConfig) + task-plugins: + # -- [Enabled Plugins](https://pkg.go.dev/github.com/flyteorg/flyteplugins/go/tasks/config#Config). + # plugins + enabled-plugins: + - container + - sidecar + - k8s-array + - sagemaker_training + - sagemaker_hyperparameter_tuning + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + +Upgrade the Flyte Helm release +============================== + +.. prompt:: bash $ + + helm upgrade -n flyte -f values-override.yaml flyteorg/flyte-core + + +Register the Sagemaker plugin example +===================================== + +.. prompt:: bash $ + + flytectl register files https://github.com/flyteorg/flytesnacks/releases/download/v0.3.0/snacks-cookbook-integrations-aws-sagemaker_training.tar.gz --archive -p flytesnacks -d development + + +Launch an execution +=================== + +.. tabs:: + + .. tab:: Flyte Console + + * Navigate to Flyte Console's UI (e.g. `sandbox `_) and find the workflow. + * Click on `Launch` to open up the launch form. + * Submit the form. + + .. tab:: Flytectl + + Retrieve an execution form in the form of a YAML file: + + .. code-block:: bash + + flytectl get launchplan --config ~/.flyte/flytectl.yaml \ + --project flytesnacks \ + --domain development \ + sagemaker_training.sagemaker_custom_training.mnist_trainer \ + --latest \ + --execFile exec_spec.yaml + + Launch! 🚀 + + .. code-block:: bash + + flytectl --config ~/.flyte/flytectl.yaml create execution \ + -p -d --execFile ~/exec_spec.yaml diff --git a/docs/deployment/plugins/gcp/bigquery.rst b/docs/deployment/plugins/gcp/bigquery.rst new file mode 100644 index 0000000000..03b21e02e1 --- /dev/null +++ b/docs/deployment/plugins/gcp/bigquery.rst @@ -0,0 +1,90 @@ +.. _deployment-plugin-setup-gcp-bigquery: + +Google BigQuery Plugin +====================== + +This guide provides an overview of setting up BigQuery in your Flyte deployment. +Please note that the BigQuery plugin requires Flyte deployment in the GCP cloud; +it is not compatible with demo/AWS/Azure. + +Set up the GCP Flyte cluster +---------------------------- + +* Ensure you have a functional Flyte cluster running in `GCP `__. +* Create a service account for BigQuery. For more details, refer to: https://cloud.google.com/bigquery/docs/quickstarts/quickstart-client-libraries. +* Verify that you have the correct kubeconfig and have selected the appropriate Kubernetes context. +* Confirm that you have the correct Flytectl configuration at ``~/.flyte/config.yaml``. + +Specify plugin configuration +---------------------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + Edit the relevant YAML file to specify the plugin. + + .. code-block:: yaml + :emphasize-lines: 7,11 + + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - bigquery + default-for-task-types: + - container: container + - container_array: k8s-array + - bigquery_query_job_task: bigquery + + .. group-tab:: Flyte core + + Create a file named ``values-override.yaml`` and add the following configuration to it. + + .. code-block:: yaml + + configmap: + enabled_plugins: + # -- Tasks specific configuration [structure](https://pkg.go.dev/github.com/flyteorg/flytepropeller/pkg/controller/nodes/task/config#GetConfig) + tasks: + # -- Plugins configuration, [structure](https://pkg.go.dev/github.com/flyteorg/flytepropeller/pkg/controller/nodes/task/config#TaskPluginConfig) + task-plugins: + # -- [Enabled Plugins](https://pkg.go.dev/github.com/flyteorg/flyteplugins/go/tasks/config#Config). Enable sagemaker*, athena if you install the backend + enabled-plugins: + - container + - sidecar + - k8s-array + - bigquery + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + bigquery_query_job_task: bigquery + +Ensure that the propeller has the correct service account for BigQuery. + +Upgrade the Flyte Helm release +------------------------------ + +.. tabs:: + + .. group-tab:: Flyte binary + + .. code-block:: bash + + helm upgrade flyteorg/flyte-binary -n --values + + Replace ```` with the name of your release (e.g., ``flyte-backend``), + ```` with the name of your namespace (e.g., ``flyte``), + and ```` with the name of your YAML file. + + .. group-tab:: Flyte core + + .. code-block:: bash + + helm upgrade flyte/flyte-core -n --values values-override.yaml + + Replace ```` with the name of your release (e.g., ``flyte``) + and ```` with the name of your namespace (e.g., ``flyte``). diff --git a/docs/deployment/plugins/gcp/index.md b/docs/deployment/plugins/gcp/index.md new file mode 100644 index 0000000000..5f7172ce75 --- /dev/null +++ b/docs/deployment/plugins/gcp/index.md @@ -0,0 +1,25 @@ +(deployment-plugin-setup-gcp)= + +# Configure GCP Plugins + +```{eval-rst} +.. tags:: GCP, Integration, Data, Advanced +``` + +Discover the process of setting up GCP plugins for Flyte. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {ref}`Google BigQuery ` + - Guide to setting up the Google BigQuery plugin. +``` + +```{toctree} +:maxdepth: 1 +:name: GCP plugin setup +:hidden: + +bigquery +``` diff --git a/docs/deployment/plugins/index.md b/docs/deployment/plugins/index.md new file mode 100644 index 0000000000..8f43627642 --- /dev/null +++ b/docs/deployment/plugins/index.md @@ -0,0 +1,34 @@ +(deployment-plugin-setup)= + +# Plugin Setup + +Flyte integrates with a wide variety of [data, ML and analytical tools](https://flyte.org/integrations) +Some of these plugins, such as Databricks, Kubeflow, and Ray integrations, require the Flyte cluster administrator to enable them. + +This section of the *Deployment Guides* will cover how to configure your cluster +to use these plugins in your workflows written in `flytekit`. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {ref}`K8s Plugins ` + - Guide to setting up the K8s Operator Plugins. +* - {ref}`Web API Plugin ` + - Guide to setting up the Web API Plugins. +* - {ref}`AWS Plugins ` + - Guide to setting up AWS-specific Plugins. +* - {ref}`GCP Plugins ` + - Guide to setting up GCP-specific Plugins. +``` + +```{toctree} +:maxdepth: 1 +:name: Plugin Setup +:hidden: + +k8s/index +aws/index +gcp/index +webapi/index +``` \ No newline at end of file diff --git a/docs/deployment/plugins/k8s/index.rst b/docs/deployment/plugins/k8s/index.rst new file mode 100644 index 0000000000..53b6ebd543 --- /dev/null +++ b/docs/deployment/plugins/k8s/index.rst @@ -0,0 +1,833 @@ +.. _deployment-plugin-setup-k8s: + +Configure Kubernetes Plugins +============================ + +.. tags:: Kubernetes, Integration, Spark, AWS, GCP, Advanced + +This guide provides an overview of setting up the Kubernetes Operator backend plugin in your Flyte deployment. + +Spin up a cluster +----------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + .. tabs:: + + .. group-tab:: Demo cluster + + .. tabs:: + + .. group-tab:: PyTorch + + Enable the PyTorch plugin on the demo cluster by adding the following block to ``~/.flyte/sandbox/config.yaml``: + + .. code-block:: yaml + + tasks: + task-plugins: + default-for-task-types: + container: container + container_array: k8s-array + sidecar: sidecar + pytorch: pytorch + enabled-plugins: + - container + - k8s-array + - sidecar + - pytorch + + .. group-tab:: TensorFlow + + Enable the TensorFlow plugin on the demo cluster by adding the following block to ``~/.flyte/sandbox/config.yaml``: + + .. code-block:: yaml + + tasks: + task-plugins: + default-for-task-types: + container: container + container_array: k8s-array + sidecar: sidecar + tensorflow: tensorflow + enabled-plugins: + - container + - k8s-array + - sidecar + - tensorflow + + .. group-tab:: MPI + + Enable the MPI plugin on the demo cluster by adding the following block to ``~/.flyte/sandbox/config.yaml``: + + .. code-block:: yaml + + tasks: + task-plugins: + default-for-task-types: + container: container + container_array: k8s-array + sidecar: sidecar + mpi: mpi + enabled-plugins: + - container + - k8s-array + - sidecar + - mpi + + .. group-tab:: Ray + + Enable the Ray plugin on the demo cluster by adding the following block to ``~/.flyte/sandbox/config.yaml``: + + .. code-block:: yaml + + tasks: + task-plugins: + default-for-task-types: + container: container + container_array: k8s-array + sidecar: sidecar + ray: ray + enabled-plugins: + - container + - k8s-array + - sidecar + - ray + + .. group-tab:: Spark + + Enable the Spark plugin on the demo cluster by adding the following config to ``~/.flyte/sandbox/config.yaml``: + + .. code-block:: yaml + + tasks: + task-plugins: + default-for-task-types: + container: container + container_array: k8s-array + sidecar: sidecar + spark: spark + enabled-plugins: + - container + - sidecar + - k8s-array + - spark + plugins: + spark: + spark-config-default: + - spark.driver.cores: "1" + - spark.hadoop.fs.s3a.aws.credentials.provider: "org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider" + - spark.hadoop.fs.s3a.endpoint: "http://minio.flyte:9000" + - spark.hadoop.fs.s3a.access.key: "minio" + - spark.hadoop.fs.s3a.secret.key: "miniostorage" + - spark.hadoop.fs.s3a.path.style.access: "true" + - spark.kubernetes.allocation.batch.size: "50" + - spark.hadoop.fs.s3a.acl.default: "BucketOwnerFullControl" + - spark.hadoop.fs.s3n.impl: "org.apache.hadoop.fs.s3a.S3AFileSystem" + - spark.hadoop.fs.AbstractFileSystem.s3n.impl: "org.apache.hadoop.fs.s3a.S3A" + - spark.hadoop.fs.s3.impl: "org.apache.hadoop.fs.s3a.S3AFileSystem" + - spark.hadoop.fs.AbstractFileSystem.s3.impl: "org.apache.hadoop.fs.s3a.S3A" + - spark.hadoop.fs.s3a.impl: "org.apache.hadoop.fs.s3a.S3AFileSystem" + - spark.hadoop.fs.AbstractFileSystem.s3a.impl: "org.apache.hadoop.fs.s3a.S3A" + cluster_resources: + refreshInterval: 5m + customData: + - production: + - projectQuotaCpu: + value: "5" + - projectQuotaMemory: + value: "4000Mi" + - staging: + - projectQuotaCpu: + value: "2" + - projectQuotaMemory: + value: "3000Mi" + - development: + - projectQuotaCpu: + value: "4" + - projectQuotaMemory: + value: "5000Mi" + refresh: 5m + + Also add the following cluster resource templates to the ``~/.flyte/sandbox/cluster-resource-templates`` directory: + + 1. ``serviceaccount.yaml`` + + .. code-block:: yaml + + apiVersion: v1 + kind: ServiceAccount + metadata: + name: default + namespace: "{{ namespace }}" + annotations: + eks.amazonaws.com/role-arn: "{{ defaultIamRole }}" + + 2. ``spark_role.yaml`` + + .. code-block:: yaml + + apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: spark-role + namespace: "{{ namespace }}" + rules: + - apiGroups: + - "" + resources: + - pods + - services + - configmaps + verbs: + - "*" + + 3. ``spark_service_account.yaml`` + + .. code-block:: yaml + + apiVersion: v1 + kind: ServiceAccount + metadata: + name: spark + namespace: "{{ namespace }}" + annotations: + eks.amazonaws.com/role-arn: "{{ defaultIamRole }}" + + 4. ``spark_role_binding.yaml`` + + .. code-block:: yaml + + apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: spark-role-binding + namespace: "{{ namespace }}" + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: spark-role + subjects: + - kind: ServiceAccount + name: spark + namespace: "{{ namespace }}" + + .. group-tab:: Dask + + Enable the Dask plugin on the demo cluster by adding the following block to ``~/.flyte/sandbox/config.yaml``: + + .. code-block:: yaml + + tasks: + task-plugins: + default-for-task-types: + container: container + container_array: k8s-array + sidecar: sidecar + dask: dask + enabled-plugins: + - container + - k8s-array + - sidecar + - dask + + Start the demo cluster by running the following command: + + .. code-block:: bash + + flytectl demo start + + .. group-tab:: Helm chart + + 1. Add the following to your values file under `configmap.inline`: + + .. code-block:: yaml + + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - K8S-ARRAY + - spark + - ray + default-for-task-types: + - container: container + - container_array: K8S-ARRAY + - spark: spark + - ray: ray + + 2. Install the :ref:`flyte-binary Helm chart `. + + .. group-tab:: Flyte core + + If you have installed Flyte using the `flyte-core Helm chart + `__, please ensure: + + * You have the correct kubeconfig and have selected the correct Kubernetes context. + * You have configured the correct flytectl settings in ``~/.flyte/config.yaml``. + +.. note:: + + Add the Flyte chart repo to Helm if you're installing via the Helm charts. + + .. code-block:: bash + + helm repo add flyteorg https://flyteorg.github.io/flyte + +Install the Kubernetes operator +------------------------------- + +.. tabs:: + + .. group-tab:: PyTorch/TensorFlow/MPI + + First, `install kustomize `__. + + Build and apply the training-operator. + + .. code-block:: bash + + export KUBECONFIG=$KUBECONFIG:~/.kube/config:~/.flyte/k3s/k3s.yaml + kustomize build "https://github.com/kubeflow/training-operator.git/manifests/overlays/standalone?ref=v1.5.0" | kubectl apply -f - + + **Optional: Using a gang scheduler** + + To address potential issues with worker pods of distributed training jobs being scheduled at different times + due to resource constraints, you can opt for a gang scheduler. This ensures that all worker pods are scheduled + simultaneously, reducing the likelihood of job failures caused by timeout errors. + + To `enable gang scheduling for the Kubeflow training-operator `__, + you can install the `Kubernetes scheduler plugins `__ + or the `Apache YuniKorn scheduler `__. + + 1. Install the `scheduler plugin `_ or + `Apache YuniKorn `_ as a second scheduler. + 2. Configure the Kubeflow training-operator to use the new scheduler: + + Create a manifest called ``kustomization.yaml`` with the following content: + + .. code-block:: yaml + + apiVersion: kustomize.config.k8s.io/v1beta1 + kind: Kustomization + + resources: + - github.com/kubeflow/training-operator/manifests/overlays/standalone + + patchesStrategicMerge: + - patch.yaml + + Create a patch file called ``patch.yaml`` with the following content: + + .. code-block:: yaml + + apiVersion: apps/v1 + kind: Deployment + metadata: + name: training-operator + spec: + template: + spec: + containers: + - name: training-operator + command: + - /manager + - --gang-scheduler-name= + + Install the patched kustomization with the following command: + + .. code-block:: bash + + kustomize build path/to/overlay/directory | kubectl apply -f - + + (Only for Apache YuniKorn) To configure gang scheduling with Apache YuniKorn, + make sure to set the following annotations in Flyte pod templates: + + - ``template.metadata.annotations.yunikorn.apache.org/task-group-name`` + - ``template.metadata.annotations.yunikorn.apache.org/task-groups`` + - ``template.metadata.annotations.yunikorn.apache.org/schedulingPolicyParameters`` + + For more configuration details, + refer to the `Apache YuniKorn Gang-Scheduling documentation + `__. + + 3. Use a Flyte pod template with ``template.spec.schedulerName: scheduler-plugins-scheduler`` + to use the new gang scheduler for your tasks. + + See the :ref:`using-k8s-podtemplates` section for more information on pod templates in Flyte. + You can set the scheduler name in the pod template passed to the ``@task`` decorator. However, to prevent the + two different schedulers from competing for resources, it is recommended to set the scheduler name in the pod template + in the ``flyte`` namespace which is applied to all tasks. Non distributed training tasks can be scheduled by the + gang scheduler as well. + + + For more information on pod templates in Flyte, refer to the :ref:`using-k8s-podtemplates` section. + You can set the scheduler name in the pod template passed to the ``@task`` decorator. + However, to avoid resource competition between the two different schedulers, + it is recommended to set the scheduler name in the pod template in the ``flyte`` namespace, + which is applied to all tasks. This allows non-distributed training tasks to be + scheduled by the gang scheduler as well. + + .. group-tab:: Ray + + To install the Ray Operator, run the following commands: + + .. code-block:: bash + + export KUBERAY_VERSION=v0.5.2 + kubectl create -k "github.com/ray-project/kuberay/manifests/cluster-scope-resources?ref=${KUBERAY_VERSION}&timeout=90s" + kubectl apply -k "github.com/ray-project/kuberay/manifests/base?ref=${KUBERAY_VERSION}&timeout=90s" + + .. group-tab:: Spark + + To add the Spark repository, run the following commands: + + .. code-block:: bash + + helm repo add spark-operator https://googlecloudplatform.github.io/spark-on-k8s-operator + + To install the Spark operator, run the following command: + + .. code-block:: bash + + helm install spark-operator spark-operator/spark-operator --namespace spark-operator --create-namespace + + .. group-tab:: Dask + + To add the Dask repository, run the following command: + + .. code-block:: bash + + helm repo add dask https://helm.dask.org + + To install the Dask operator, run the following command: + + .. code-block:: bash + + helm install dask-operator dask/dask-kubernetes-operator --namespace dask-operator --create-namespace + +Specify plugin configuration +---------------------------- + +.. tabs:: + + .. group-tab:: PyTorch + + .. tabs:: + + .. group-tab:: Flyte binary + + To specify the plugin when using the Helm chart, edit the relevant YAML file. + + .. code-block:: yaml + :emphasize-lines: 7,11 + + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - pytorch + default-for-task-types: + - container: container + - container_array: k8s-array + - pytorch: pytorch + + .. group-tab:: Flyte core + + Create a file named ``values-override.yaml`` and add the following config to it: + + .. code-block:: yaml + + configmap: + enabled_plugins: + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - pytorch + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + pytorch: pytorch + + .. group-tab:: TensorFlow + + .. tabs:: + + .. group-tab:: Flyte binary + + To specify the plugin when using the Helm chart, edit the relevant YAML file. + + .. code-block:: yaml + :emphasize-lines: 7,11 + + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - tensorflow + default-for-task-types: + - container: container + - container_array: k8s-array + - tensorflow: tensorflow + + .. group-tab:: Flyte core + + Create a file named ``values-override.yaml`` and add the following config to it: + + .. code-block:: yaml + + configmap: + enabled_plugins: + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - tensorflow + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + tensorflow: tensorflow + + .. group-tab:: MPI + + .. tabs:: + + .. group-tab:: Flyte binary + + To specify the plugin when using the Helm chart, edit the relevant YAML file. + + .. code-block:: yaml + :emphasize-lines: 7,11 + + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - mpi + default-for-task-types: + - container: container + - container_array: k8s-array + - mpi: mpi + + .. group-tab:: Flyte core + + Create a file named ``values-override.yaml`` and add the following config to it: + + .. code-block:: yaml + + configmap: + enabled_plugins: + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - mpi + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + mpi: mpi + + .. group-tab:: Ray + + .. tabs:: + + .. group-tab:: Flyte binary + + 1. Make sure that your Helm values file includes the following configuration: + + .. code-block:: yaml + + configuration: + inline: + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - ray + default-for-task-types: + - container: container + - container_array: k8s-array + - ray: ray + + rbac: + extraRules: + - apiGroups: + - "ray.io" + resources: + - rayjob + verbs: + - create + - get + - list + - patch + - update + + 2. Run a ``helm upgrade`` operation + + .. group-tab:: Flyte core + + Create a file named ``values-override.yaml`` and add the following config to it: + + .. code-block:: yaml + + configmap: + enabled_plugins: + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - ray + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + ray: ray + + .. group-tab:: Spark + + .. tabs:: + + .. group-tab:: Flyte binary + + To specify the plugin when using the Helm chart, edit the relevant YAML file. + + .. group-tab:: Flyte core + + Create a file named ``values-override.yaml`` and add the following config to it: + + .. code-block:: yaml + + cluster_resource_manager: + enabled: true + config: + cluster_resources: + refreshInterval: 5m + templatePath: "/etc/flyte/clusterresource/templates" + customData: + - production: + - projectQuotaCpu: + value: "5" + - projectQuotaMemory: + value: "4000Mi" + - staging: + - projectQuotaCpu: + value: "2" + - projectQuotaMemory: + value: "3000Mi" + - development: + - projectQuotaCpu: + value: "4" + - projectQuotaMemory: + value: "3000Mi" + refresh: 5m + + # -- Resource templates that should be applied + templates: + # -- Template for namespaces resources + - key: aa_namespace + value: | + apiVersion: v1 + kind: Namespace + metadata: + name: {{ namespace }} + spec: + finalizers: + - kubernetes + + - key: ab_project_resource_quota + value: | + apiVersion: v1 + kind: ResourceQuota + metadata: + name: project-quota + namespace: {{ namespace }} + spec: + hard: + limits.cpu: {{ projectQuotaCpu }} + limits.memory: {{ projectQuotaMemory }} + + - key: ac_spark_role + value: | + apiVersion: rbac.authorization.k8s.io/v1beta1 + kind: Role + metadata: + name: spark-role + namespace: {{ namespace }} + rules: + - apiGroups: ["*"] + resources: + - pods + verbs: + - '*' + - apiGroups: ["*"] + resources: + - services + verbs: + - '*' + - apiGroups: ["*"] + resources: + - configmaps + verbs: + - '*' + + - key: ad_spark_service_account + value: | + apiVersion: v1 + kind: ServiceAccount + metadata: + name: spark + namespace: {{ namespace }} + + - key: ae_spark_role_binding + value: | + apiVersion: rbac.authorization.k8s.io/v1beta1 + kind: RoleBinding + metadata: + name: spark-role-binding + namespace: {{ namespace }} + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: spark-role + subjects: + - kind: ServiceAccount + name: spark + namespace: {{ namespace }} + + sparkoperator: + enabled: true + plugin_config: + plugins: + spark: + # Edit the Spark configuration as you see fit + spark-config-default: + - spark.driver.cores: "1" + - spark.hadoop.fs.s3a.aws.credentials.provider: "com.amazonaws.auth.DefaultAWSCredentialsProviderChain" + - spark.kubernetes.allocation.batch.size: "50" + - spark.hadoop.fs.s3a.acl.default: "BucketOwnerFullControl" + - spark.hadoop.fs.s3n.impl: "org.apache.hadoop.fs.s3a.S3AFileSystem" + - spark.hadoop.fs.AbstractFileSystem.s3n.impl: "org.apache.hadoop.fs.s3a.S3A" + - spark.hadoop.fs.s3.impl: "org.apache.hadoop.fs.s3a.S3AFileSystem" + - spark.hadoop.fs.AbstractFileSystem.s3.impl: "org.apache.hadoop.fs.s3a.S3A" + - spark.hadoop.fs.s3a.impl: "org.apache.hadoop.fs.s3a.S3AFileSystem" + - spark.hadoop.fs.AbstractFileSystem.s3a.impl: "org.apache.hadoop.fs.s3a.S3A" + - spark.network.timeout: 600s + - spark.executorEnv.KUBERNETES_REQUEST_TIMEOUT: 100000 + - spark.executor.heartbeatInterval: 60s + configmap: + enabled_plugins: + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - spark + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + spark: spark + + .. group-tab:: Dask + + .. tabs:: + + .. group-tab:: Flyte binary + + Edit the relevant YAML file to specify the plugin. + + .. code-block:: yaml + :emphasize-lines: 7,11 + + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - dask + default-for-task-types: + - container: container + - container_array: k8s-array + - dask: dask + + .. group-tab:: Flyte core + + Create a file named ``values-override.yaml`` and add the following config to it: + + .. code-block:: yaml + + configmap: + enabled_plugins: + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - dask + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + dask: dask + +Upgrade the deployment +---------------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + If you are installing Flyte via the Helm chart, run the following command: + + .. note:: + + There is no need to run ``helm upgrade`` for Spark. + + .. code-block:: bash + + helm upgrade flyteorg/flyte-binary -n --values + + Replace ```` with the name of your release (e.g., ``flyte-backend``), + ```` with the name of your namespace (e.g., ``flyte``), + and ```` with the name of your YAML file. + + .. group-tab:: Flyte core + + .. code-block:: bash + + helm upgrade flyte/flyte-core -n --values values-override.yaml + + Replace ```` with the name of your release (e.g., ``flyte``) + and ```` with the name of your namespace (e.g., ``flyte``). + +Wait for the upgrade to complete. You can check the status of the deployment pods by running the following command: + +.. code-block:: bash + + kubectl get pods -n --all-namespaces diff --git a/docs/deployment/plugins/webapi/databricks.rst b/docs/deployment/plugins/webapi/databricks.rst new file mode 100644 index 0000000000..671fdb4e18 --- /dev/null +++ b/docs/deployment/plugins/webapi/databricks.rst @@ -0,0 +1,383 @@ +.. _deployment-plugin-setup-webapi-databricks: + +Databricks Plugin +================= + +This guide provides an overview of how to set up Databricks in your Flyte deployment. + +Spin up a cluster +----------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + You can spin up a demo cluster using the following command: + + .. code-block:: bash + + flytectl demo start + + Or install Flyte using the :ref:`flyte-binary helm chart `. + + .. group-tab:: Flyte core + + If you've installed Flyte using the + `flyte-core helm chart `__, please ensure: + + * You have the correct kubeconfig and have selected the correct Kubernetes context. + * You have configured the correct flytectl settings in ``~/.flyte/config.yaml``. + +.. note:: + + Add the Flyte chart repo to Helm if you're installing via the Helm charts. + + .. code-block:: bash + + helm repo add flyteorg https://flyteorg.github.io/flyte + +Databricks workspace +-------------------- + +To set up your Databricks account, follow these steps: + +1. Create a `Databricks account `__. +2. Ensure that you have a Databricks workspace up and running. +3. Generate a `personal access token + `__ to be used in the Flyte configuration. + You can find the personal access token in the user settings within the workspace. + +.. note:: + + When testing the Databricks plugin on the demo cluster, create an S3 bucket because the local demo + cluster utilizes MinIO. Follow the `AWS instructions + `__ + to generate access and secret keys, which can be used to access your preferred S3 bucket. + +Create an `instance profile +`__ +for the Spark cluster. This profile enables the Spark job to access your data in the S3 bucket. +Please follow all four steps specified in the documentation. + +Upload the following entrypoint.py file to either +`DBFS `__ +(the final path can be ``dbfs:///FileStore/tables/entrypoint.py``) or S3. +This file will be executed by the Spark driver node, overriding the default command in the +`dbx `__ job. + +.. TODO: A quick-and-dirty workaround to resolve https://github.com/flyteorg/flyte/issues/3853 issue is to import pandas. + +.. code-block:: python + + import os + import sys + from typing import List + + import click + import pandas + from flytekit.bin.entrypoint import fast_execute_task_cmd as _fast_execute_task_cmd + from flytekit.bin.entrypoint import execute_task_cmd as _execute_task_cmd + from flytekit.exceptions.user import FlyteUserException + from flytekit.tools.fast_registration import download_distribution + + + def fast_execute_task_cmd(additional_distribution: str, dest_dir: str, task_execute_cmd: List[str]): + if additional_distribution is not None: + if not dest_dir: + dest_dir = os.getcwd() + download_distribution(additional_distribution, dest_dir) + + # Insert the call to fast before the unbounded resolver args + cmd = [] + for arg in task_execute_cmd: + if arg == "--resolver": + cmd.extend(["--dynamic-addl-distro", additional_distribution, "--dynamic-dest-dir", dest_dir]) + cmd.append(arg) + + click_ctx = click.Context(click.Command("dummy")) + parser = _execute_task_cmd.make_parser(click_ctx) + args, _, _ = parser.parse_args(cmd[1:]) + _execute_task_cmd.callback(test=False, **args) + + + def main(): + + args = sys.argv + + click_ctx = click.Context(click.Command("dummy")) + if args[1] == "pyflyte-fast-execute": + parser = _fast_execute_task_cmd.make_parser(click_ctx) + args, _, _ = parser.parse_args(args[2:]) + fast_execute_task_cmd(**args) + elif args[1] == "pyflyte-execute": + parser = _execute_task_cmd.make_parser(click_ctx) + args, _, _ = parser.parse_args(args[2:]) + _execute_task_cmd.callback(test=False, dynamic_addl_distro=None, dynamic_dest_dir=None, **args) + else: + raise FlyteUserException(f"Unrecognized command: {args[1:]}") + + + if __name__ == '__main__': + main() + +Specify plugin configuration +---------------------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + .. tabs:: + + .. group-tab:: Demo cluster + + Enable the Databricks plugin on the demo cluster by adding the following config to ``~/.flyte/sandbox/config.yaml``: + + .. code-block:: yaml + + tasks: + task-plugins: + default-for-task-types: + container: container + container_array: k8s-array + sidecar: sidecar + spark: databricks + enabled-plugins: + - container + - sidecar + - k8s-array + - databricks + plugins: + databricks: + entrypointFile: dbfs:///FileStore/tables/entrypoint.py + databricksInstance: .cloud.databricks.com + k8s: + default-env-vars: + - FLYTE_AWS_ACCESS_KEY_ID: + - FLYTE_AWS_SECRET_ACCESS_KEY: + - AWS_DEFAULT_REGION: + remoteData: + region: + scheme: aws + signedUrls: + durationMinutes: 3 + propeller: + rawoutput-prefix: s3:/// + storage: + container: "" + type: s3 + stow: + kind: s3 + config: + region: + disable_ssl: true + v2_signing: false + auth_type: accesskey + access_key_id: + secret_key: + signedURL: + stowConfigOverride: + endpoint: "" + + Substitute ```` with the name of your Databricks account, + ```` with the region where you created your AWS bucket, + ```` with your AWS access key ID, + ```` with your AWS secret access key, + and ```` with the name of your S3 bucket. + + .. group-tab:: Helm chart + + Edit the relevant YAML file to specify the plugin. + + .. code-block:: yaml + :emphasize-lines: 7,11 + + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - databricks + default-for-task-types: + - container: container + - container_array: k8s-array + - spark: databricks + + .. code-block:: yaml + :emphasize-lines: 3-5 + + inline: + plugins: + databricks: + entrypointFile: dbfs:///FileStore/tables/entrypoint.py + databricksInstance: .cloud.databricks.com + + Substitute ```` with the name of your Databricks account. + + .. group-tab:: Flyte core + + Create a file named ``values-override.yaml`` and add the following config to it: + + .. code-block:: yaml + :emphasize-lines: 9,14,15-21 + + configmap: + enabled_plugins: + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - databricks + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + spark: databricks + databricks: + enabled: True + plugin_config: + plugins: + databricks: + entrypointFile: dbfs:///FileStore/tables/entrypoint.py + databricksInstance: .cloud.databricks.com + + Substitute ```` with the name of your Databricks account. + +Add the Databricks access token +------------------------------- + +Add the Databricks access token to FlytePropeller: + +.. tabs:: + + .. group-tab:: Flyte binary + + .. tabs:: + + .. group-tab:: Demo cluster + + Add the access token as an environment variable to the ``flyte-sandbox`` deployment. + + .. code-block:: bash + + kubectl edit deploy flyte-sandbox -n flyte + + Update the ``env`` configuration: + + .. code-block:: yaml + :emphasize-lines: 12-13 + + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: FLYTE_SECRET_FLYTE_DATABRICKS_API_TOKEN + value: + image: flyte-binary:sandbox + ... + + .. group-tab:: Helm chart + + Create an external secret as follows: + + .. code-block:: bash + + cat < + EOF + + Reference the newly created secret in + ``.Values.configuration.auth.clientSecretsExternalSecretRef`` + in your YAML file as follows: + + .. code-block:: yaml + :emphasize-lines: 3 + + configuration: + auth: + clientSecretsExternalSecretRef: flyte-binary-client-secrets-external-secret + + Replace ```` with your access token. + + .. group-tab:: Flyte core + + Add the access token as a secret to ``flyte-secret-auth``. + + .. code-block:: bash + + kubectl edit secret -n flyte flyte-secret-auth + + .. code-block:: yaml + :emphasize-lines: 3 + + apiVersion: v1 + data: + FLYTE_DATABRICKS_API_TOKEN: + client_secret: Zm9vYmFy + kind: Secret + ... + + Replace ```` with your access token. + +Upgrade the deployment +---------------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + .. tabs:: + + .. group-tab:: Demo cluster + + .. code-block:: bash + + kubectl rollout restart deployment flyte-sandbox -n flyte + + .. group-tab:: Helm chart + + .. code-block:: bash + + helm upgrade flyteorg/flyte-binary -n --values + + Replace ```` with the name of your release (e.g., ``flyte-backend``), + ```` with the name of your namespace (e.g., ``flyte``), + and ```` with the name of your YAML file. + + .. group-tab:: Flyte core + + .. code-block:: + + helm upgrade flyte/flyte-core -n --values values-override.yaml + + Replace ```` with the name of your release (e.g., ``flyte``) + and ```` with the name of your namespace (e.g., ``flyte``). + +Wait for the upgrade to complete. You can check the status of the deployment pods by running the following command: + +.. code-block:: + + kubectl get pods -n flyte + +.. note:: + + Make sure you enable `custom containers + `__ + on your Databricks cluster before you trigger the workflow. \ No newline at end of file diff --git a/docs/deployment/plugins/webapi/index.md b/docs/deployment/plugins/webapi/index.md new file mode 100644 index 0000000000..85191e0fb1 --- /dev/null +++ b/docs/deployment/plugins/webapi/index.md @@ -0,0 +1,28 @@ +(deployment-plugin-setup-webapi)= + +# Configure Web APIs + +```{eval-rst} +.. tags:: WebAPI, Integration, Data, Advanced +``` + +Discover the process of setting up Web API plugins for Flyte. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {ref}`Snowflake Plugin ` + - Guide to setting up the Snowflake plugin. +* - {ref}`Databricks Plugin ` + - Guide to setting up the Databricks plugin. +``` + +```{toctree} +:maxdepth: 1 +:name: Web API plugin setup +:hidden: + +snowflake +databricks +``` diff --git a/docs/deployment/plugins/webapi/snowflake.rst b/docs/deployment/plugins/webapi/snowflake.rst new file mode 100644 index 0000000000..85f13fe115 --- /dev/null +++ b/docs/deployment/plugins/webapi/snowflake.rst @@ -0,0 +1,243 @@ +.. _deployment-plugin-setup-webapi-snowflake: + +Snowflake Plugin +================ + +This guide provides an overview of how to set up Snowflake in your Flyte deployment. + +Spin up a cluster +----------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + You can spin up a demo cluster using the following command: + + .. code-block:: bash + + flytectl demo start + + Or install Flyte using the :ref:`flyte-binary helm chart `. + + .. group-tab:: Flyte core + + If you've installed Flyte using the + `flyte-core helm chart `__, + please ensure: + + * You have the correct kubeconfig and have selected the correct Kubernetes context. + * You have configured the correct flytectl settings in ``~/.flyte/config.yaml``. + +.. note:: + + Add the Flyte chart repo to Helm if you're installing via the Helm charts. + + .. code-block:: bash + + helm repo add flyteorg https://flyteorg.github.io/flyte + +Specify plugin configuration +---------------------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + .. tabs:: + + .. group-tab:: Demo cluster + + Enable the Snowflake plugin on the demo cluster by adding the following block to ``~/.flyte/sandbox/config.yaml``: + + .. code-block:: yaml + + tasks: + task-plugins: + default-for-task-types: + container: container + container_array: k8s-array + sidecar: sidecar + snowflake: snowflake + enabled-plugins: + - container + - k8s-array + - sidecar + - snowflake + + .. group-tab:: Helm chart + + Edit the relevant YAML file to specify the plugin. + + .. code-block:: yaml + :emphasize-lines: 7,11 + + tasks: + task-plugins: + enabled-plugins: + - container + - sidecar + - k8s-array + - snowflake + default-for-task-types: + - container: container + - container_array: k8s-array + - snowflake: snowflake + + .. group-tab:: Flyte core + + Create a file named ``values-override.yaml`` and add the following config to it: + + .. code-block:: yaml + + configmap: + enabled_plugins: + # -- Tasks specific configuration [structure](https://pkg.go.dev/github.com/flyteorg/flytepropeller/pkg/controller/nodes/task/config#GetConfig) + tasks: + # -- Plugins configuration, [structure](https://pkg.go.dev/github.com/flyteorg/flytepropeller/pkg/controller/nodes/task/config#TaskPluginConfig) + task-plugins: + # -- [Enabled Plugins](https://pkg.go.dev/github.com/flyteorg/flyteplugins/go/tasks/config#Config). Enable sagemaker*, athena if you install the backend + # plugins + enabled-plugins: + - container + - sidecar + - k8s-array + - snowflake + default-for-task-types: + container: container + sidecar: sidecar + container_array: k8s-array + snowflake: snowflake + +Obtain and add the Snowflake JWT token +-------------------------------------- + +Create a Snowflake account, and follow the `Snowflake docs +`__ +to generate a JWT token. +Then, add the Snowflake JWT token to FlytePropeller. + +.. tabs:: + + .. group-tab:: Flyte binary + + .. tabs:: + + .. group-tab:: Demo cluster + + Add the JWT token as an environment variable to the ``flyte-sandbox`` deployment. + + .. code-block:: bash + + kubectl edit deploy flyte-sandbox -n flyte + + Update the ``env`` configuration: + + .. code-block:: yaml + :emphasize-lines: 12-13 + + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: FLYTE_SECRET_FLYTE_SNOWFLAKE_CLIENT_TOKEN + value: + image: flyte-binary:sandbox + ... + + .. group-tab:: Helm chart + + Create an external secret as follows: + + .. code-block:: bash + + cat < + EOF + + Reference the newly created secret in + ``.Values.configuration.auth.clientSecretsExternalSecretRef`` + in your YAML file as follows: + + .. code-block:: yaml + :emphasize-lines: 3 + + configuration: + auth: + clientSecretsExternalSecretRef: flyte-binary-client-secrets-external-secret + + Replace ```` with your JWT token. + + .. group-tab:: Flyte core + + Add the JWT token as a secret to ``flyte-secret-auth``. + + .. code-block:: bash + + kubectl edit secret -n flyte flyte-secret-auth + + .. code-block:: yaml + :emphasize-lines: 3 + + apiVersion: v1 + data: + FLYTE_SNOWFLAKE_CLIENT_TOKEN: + client_secret: Zm9vYmFy + kind: Secret + ... + + Replace ```` with your JWT token. + +Upgrade the deployment +---------------------- + +.. tabs:: + + .. group-tab:: Flyte binary + + .. tabs:: + + .. group-tab:: Demo cluster + + .. code-block:: bash + + kubectl rollout restart deployment flyte-sandbox -n flyte + + .. group-tab:: Helm chart + + .. code-block:: bash + + helm upgrade flyteorg/flyte-binary -n --values + + Replace ```` with the name of your release (e.g., ``flyte-backend``), + ```` with the name of your namespace (e.g., ``flyte``), + and ```` with the name of your YAML file. + + .. group-tab:: Flyte core + + .. code-block:: + + helm upgrade flyte/flyte-core -n --values values-override.yaml + + Replace ```` with the name of your release (e.g., ``flyte``) + and ```` with the name of your namespace (e.g., ``flyte``). + +Wait for the upgrade to complete. You can check the status of the deployment pods by running the following command: + +.. code-block:: + + kubectl get pods -n flyte \ No newline at end of file diff --git a/docs/deployment/security/index.rst b/docs/deployment/security/index.rst new file mode 100644 index 0000000000..6beccb5f95 --- /dev/null +++ b/docs/deployment/security/index.rst @@ -0,0 +1,132 @@ +.. _deployment-security-overview: + +################### +Security Overview +################### + +.. tags:: Kubernetes, Infrastructure, Advanced + +Here we cover the security aspects of running your flyte deployments. In the current state, we will cover the user +used for running the flyte services, and go through why we do this and not run them as a root user. + +************************ +Using the Non-root User +************************ + +It's considered to be a best practice to use a non-root user for security because +running in a constrained permission environment will prevent any malicious code +from utilizing the full permissions of the host `Ref `__ +Moreover, in certain container platforms like `OpenShift `__, +running non-root containers is mandatory. + +Flyte uses OCI-compatible container technology like Docker for container packaging, +and by default, its containers run as root. This gives full permissions to the +system but may not be suitable for production deployments where a security breach +could comprise your application deployments. + +.. important:: + + As a Flyte administrator, it's up to you a to enforce whatever policy complies + with the conventions and regulations of your industry/application. + +******* +Changes +******* + +A new user group and user have been added to the Docker files for all the Flyte components: +`Flyteadmin `__, +`Flytepropeller `__, +`Datacatalog `__, +`Flyteconsole `__. + +And Dockerfile uses the `USER command `__, which sets the user +and group, that's used for running the container. + +Additionally, the k8s manifest files for the flyte components define the overridden security context with the created +user and group to run them. The following shows the overridden security context added for flyteadmin +`Flyteadmin `__. + + +************ +Why override +************ +Certain init-containers still require root permissions, and hence we are required to override the security +context for these. +For example: in the case of `Flyteadmin `__, +the init container of check-db-ready that runs postgres-provided docker image cannot resolve the host for the checks and fails. This is mostly due to no read +permissions on etc/hosts file. Only the check-db-ready container is run using the root user, which we will also plan to fix. + + +************ +OAuth +************ +Flytectl requires CA-certified SSL cert for OAuth to work. Using a self-signed certificate throws the following error: + +.. code-block:: + + certificate is not standards compliant. + +There are two options to fix this: + +#. Switch to a full external OAuth Provider (okta, GCP cloud identity, keycloak, Azure AD, etc.). +#. Use a CA-certified SSL cert. + +******************************************************** +Running flyteadmin and flyteconsole on different domains +******************************************************** + +In some cases when flyteadmin and flyteconsole are running on different domains, +you'll would need to allow the flyteadmin's domain to allow cross origin request +from the flyteconsole's domain. Here are all the domains/namespaces to keep in +mind: + +- ````: the domain which will get the request. +- ````: the domain which will be sending the request as the originator. +- ````: the k8s namespace where your flyteconsole pod is running. +- ````: the k8s namespace where your flyteadmin pod is running. + +Modify FlyteAdmin Config +======================== + +To modify the FlyteConsole deployment to use ````, do the following: + +.. prompt:: bash $ + + kubectl edit deployment flyteconsole -n + +.. code-block:: yaml + + - env: + - name: ENABLE_GA + value: "true" + - name: GA_TRACKING_ID + value: G-0123456789 + - name: ADMIN_API_URL + value: https:// + +Rollout FlyteConsole + +.. prompt:: bash $ + + kubectl rollout restart deployment/flyteconsole -n + +Modify the flyte-admin-config as follows: + +.. prompt:: bash $ + + kubectl edit configmap flyte-admin-config -n + +.. code-block:: yaml + + security: + allowCors: true + ...... + allowedOrigins: + - 'https://' + ...... + +Finally, rollout FlyteAdmin + +.. prompt:: bash $ + + kubectl rollout restart deployment/flyteadmin -n diff --git a/docs/flytectl_overview.rst b/docs/flytectl_overview.rst new file mode 100644 index 0000000000..a6d104b08f --- /dev/null +++ b/docs/flytectl_overview.rst @@ -0,0 +1,107 @@ +.. flytectl doc + +#################################################### +Flytectl: The Official Flyte Command-line Interface +#################################################### + +Overview +========= +This video will take you on a tour of Flytectl - how to install and configure it, as well as how to use the Verbs and Nouns sections on the left hand side menu. Detailed information can be found in the sections below the video. + +.. youtube:: cV8ezYnBANE + + +Installation +============ + +Flytectl is a Golang binary that can be installed on any platform supported by Golang. + +.. tabbed:: OSX + + .. prompt:: bash $ + + brew install flyteorg/homebrew-tap/flytectl + + *Upgrade* existing installation using the following command: + + .. prompt:: bash $ + + flytectl upgrade + +.. tabbed:: Other Operating systems + + .. prompt:: bash $ + + curl -sL https://ctl.flyte.org/install | bash + + *Upgrade* existing installation using the following command: + + .. prompt:: bash $ + + flytectl upgrade + +**Test** if Flytectl is installed correctly (your Flytectl version should be > 0.2.0) using the following command: + +.. prompt:: bash $ + + flytectl version + +Configuration +============= + +Flytectl allows you to communicate with FlyteAdmin using a YAML file or by passing every configuration value +on the command-line. The following configuration can be used for the setup: + +Basic Configuration +-------------------- + +The full list of available configurable options can be found by running ``flytectl --help``, or `here `__. + +.. NOTE:: + + Currently, the Project ``-p``, Domain ``-d``, and Output ``-o`` flags cannot be used in the config file. + +.. tabbed:: Local Flyte Sandbox + + Automatically configured for you by ``flytectl sandbox`` command. + + .. code-block:: yaml + + admin: + # For GRPC endpoints you might want to use dns:///flyte.myexample.com + endpoint: dns:///localhost:30081 + insecure: true # Set to false to enable TLS/SSL connection (not recommended except on local sandbox deployment). + authType: Pkce # authType: Pkce # if using authentication or just drop this. + +.. tabbed:: AWS Configuration + + .. code-block:: yaml + + admin: + # For GRPC endpoints you might want to use dns:///flyte.myexample.com + endpoint: dns:/// + authType: Pkce # authType: Pkce # if using authentication or just drop this. + insecure: true # insecure: True # Set to true if the endpoint isn't accessible through TLS/SSL connection (not recommended except on local sandbox deployment) + +.. tabbed:: GCS Configuration + + .. code-block:: yaml + + admin: + # For GRPC endpoints you might want to use dns:///flyte.myexample.com + endpoint: dns:/// + authType: Pkce # authType: Pkce # if using authentication or just drop this. + insecure: false # insecure: True # Set to true if the endpoint isn't accessible through TLS/SSL connection (not recommended except on local sandbox deployment) + +.. tabbed:: Others + + For other supported storage backends like Oracle, Azure, etc., refer to the configuration structure `here `__. + + Place the config file in ``$HOME/.flyte`` directory with the name config.yaml. + This file is typically searched in: + + * ``$HOME/.flyte`` + * currDir from where you run flytectl + * ``/etc/flyte/config`` + + You can also pass the file name in the command line using ``--config ``. diff --git a/docs/images/favicon-flyte-docs.png b/docs/images/favicon-flyte-docs.png new file mode 100644 index 0000000000000000000000000000000000000000..b5e613f5d28ac29a515966fd05573e60073a0db2 GIT binary patch literal 28517 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 literal 0 HcmV?d00001 diff --git a/docs/images/flyte-and-lf.png b/docs/images/flyte-and-lf.png new file mode 100644 index 0000000000000000000000000000000000000000..47c8958805dcbe8a263900d79b02aef53b0d68f7 GIT binary patch literal 166426 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%0A)A#n%{mBmLs`Y{3GXpkvz}^3*Nku zT?nyWC!b6xVQu>=5cIpLvw1OVJH_0bNHFLi?Wo!HRjt9inC58^#G#REv%d6K=NrLd z8-v-1DgSCrdHd)DAKVy0L^T7A6!!1mq9N}}cYM;L9un1bUegd8ALu|fn3YWPQT-K$ ztR4R{R!(CZbBdI2r<`0?HYa?D*NzK&V1UlweC_tS9R~Axc-hzsJXyR&-he%sySJU4 zX=EZev`9$jX}EI>1nG^}`3{?mQ{CI>Y1lxm$&U+Pzr|U`?SS$EYX;lyMLrMzA7l2EJ01B=0p5{cD!2j#Jx@WnS3q!;@f@&$@~Gr;L87;j^Ee^TX|cc4s?xcxL0A3{!QHe{&&e`ig88OwznsJ`v}%4+CODr;6r@!~ zE&KL>`xllg!E%$bD)dlbD-|cTR%Be05vGE?6Of3ke(L)-kZ8Y5z&s*r zFd#-2L0mkXACh&rpm@{*`8DMRJOB5{$iI%<;4M$YDmNi)SA&2fcPRN~jbdsMgWh9t z*wh3ucm>8aan$SalO1W8gv@ta4P{AZty&roPx&zWsA-h6Hx>PYhI=6jTYIYiFu?0a zr}tQm^^sL!rK(*t2c_a{dIvf6F-q3#XzO*#Rnu09d)V}p;Fp0K-1!qOXV8jYbJmcOUB%MwW{G%eBZr8gL-_ZPXP@&N@WFa8gg*OK2 z9m;%YxAElErNfh6()eY;#XKEjRlJZ8wWKV@B|$LcQrLEgf%l$wr^d&$jHing>Uggg zA!k3d*xn8y6Th=p(20Bt%PBH=j8?{2##1Qj-RW6}z-jtG2yL6f<&(Q!Mi2|Ip0D?I z0tT6CNI|T{HpNTX&p#*wp1V)gHw)iCu$(+t0>C{$)X3z)ISoFICC*sylg9o|Q;%It zXHmCWN+U&2VBhZ6OLVoS>h+U8*T;YA(T@=#$%&(I`8x%2 zoF{X|`s)?B9$$NC?VTrD!bHig9i;9m(XjIao|t<~#FQTAiZ@oLy(27Vp^VaCkdje@ z(*_^r7Id{yAj79-ZZL9EDUyq|qMCbFlC9fu91I+cK7I|qF%Qro08D`Vzx3+G`o2l3 zXZOazRLF)P`2NmIotHWb+I=9&MMaeS)C`XZ`4%@x`T*-y$KGi6vP_@as6B<=5L;=w zhA%sIs~-PuIv-GH_^LjP@{kl5P{+DQeL_*sFv54xtPK zw6}{i+X0Tz)4=$tNI~zbY1n7ekgVQuR0LkzBI;ZtrE$#HQZJbJr2!k|2d*t;b+MRa zeb?~JXt@o)m-h3XQ0VgDdV3SsQPlCV_qdrxW!v5{*iZS#$|WD)!gd5BWcN5QyP-

8O{{6`|(Wc>xZ3ia*?q-GS_Iwgtuog_klzqk_Pem~NBC>)a!hitVs`rjH8 zd6u*B+I9W(Bz)*{fAYj-F@}7q;4Wwpy8`<2?T#|oL=3QNulftHh91QkHy&1n1~GCQ zH+BYO1)zlr6fi=hNeHGFL=Q>?kZq^MmiE<-?8lg)wTdC)n*z$0XPuM=@#de@e`33H zK)&Y<2u(7v>S3GW{__+HDs|woGzwS@hq((PP#Oey2)h_GSUAfw@Giv}B@YSW)dwYf zm<%#SsMvETebsM^YV=m=RZ8$n#m%#snA^!|C(lI}7b{*){Ilml-!2v{3C(b`DX%Umd&mpXM zO`{tMCYZM8QQ{i38{WGccF7UWC;~YMwrX^q2q&)m%3{+2 z61#|fZ84EkA$Jcb_kjrBBkY+eZqh7B{GbXe*&!l~xe1NGpepxS`+>TSvJAr1)t(xD zkV+W*O-{wGtXa8^Nu5KqtkM2W(>Qt+Wum%U%x?QL2Yw(m@{=R8pQ_FOlYXTB=q()6 z7CBpYh0t7vSc>4O6G6Yo>@+V)8Di<7=P4$aw2y2#-ASO|33gpt8CK7!I?sn1h`=qz z_-AWHE1*Dnx1U8RbV5DEB6VeSIq=9da;SkjY4i<$$<{^h>NDt0vZ2`ib%?C&uBKcK z=S3b_*Un>L-@w%unG>^TPX-lSU8i;6mq3~39(5(z)QiO!j$l7ETFIW zJUk4+?E0b2Kwg#&Mvok)vF{H)q7=@x#CTiRMm78Nt5gMQHtBvh4qNp4aQC57p~1aH zqZJ%?<54#E)6yQc|0c!qpw`g;dNKdw(wzC=DC*>ciw=Nz0ObRSaWI;1;yv!ZVASd< z&M=V0busp@)vK1B;!una%cbFKU!HqAI9P>ZzBl>2`?L+=+en^Zg=YX1zL(B?qUYBh z270!9@fwD)BOEE}Eqr>^x$yGaf$KCR-TKo02u3P-NnUx<3avg> zL=Q&T6dhmFJrvEanzu}0@kja(Aw2pmKb51uKG4-?igh~N3i>wlR^{(=O?YXWN`$s! z9rK6q+qOYn7Z`B7(`A9I087~-HpP2DXh*Ld6_k164pWN#>$TCypa{n*G9Y--2Q~l zwQoL+kWR4BQ!IZpH(`229=LVkQW$uNT$w~$arJyC z0IvPcm6(Te3de>?Kteh%?8wLm4FEGJNs$z1ckw4Q+)z$lSTua-34D*1V$}%HSg?w8 zZ1;Z%f>&5mgA3=(pTRKlvd}RuVT8{Q{qU24!- zqe1NWJEK?N`;&$y-t1MMOi%?e_Jv$S1rQp&TEk-fFa(NRhbeh>tq`yc4I!Jd>uZoTNK0706#4uLXyH3^S zas1ZNlDNr{VL$Du`!J4l)Tt${E)yOP-zTR-#>gG*%?FQkpfb|oXkQ@ZT9NPN6 zDnOVw&gPTs`7RX681HirC1z2vLqN8@qy9wn&Rju%qgy#*`pqSM7W_n2);tb@*;9aZ zzDg2)fpG1#C=IY@8&iNi{HiOmm%Tqe@am6=Rbn{|l4Tpw=`Cn#5SO!Hfim6^bQz zmyfqNrnU(&FQ}A&P;CHhCBzDAuW+$3p!}CGXCbt zt>C{}Vhi9M9UrYJtEO1!S5}nrhLpBucWypKsx`=sFDM1QbGRwX{uf95I#pokJkFnV z;sHUbY!CJ>)R`^k)T+g255k47-1G|`xGD`B#<~@)x>*7xoe``4Jc+Da#qmu-kSeEilsEIhc#9VYGcNEsU32&csf<6e}t=Bc2BDCT;Oj zJ7c)#O7$+RH%g;(eJb3|A#OTz=Z2WCV(756@H%?hv>1E(rhO(DDS;&@?I`WM7zz=F zU$ZN#F&DSY#Dv=0{@WxK`+TB@Zbf^|heC95adrY22ndqsEo_7iCuNvPg^Ntdy39kN1$_%sqaw> z=!0eNdsHv(_kp~j0qYa5#pV_27_2ZK7{3*YjIHzvYF}u7QwM`0y@sN|;ix z2MkhO+4lE`h{vA>^ND{rZox#eBe8jOL!3imEW@o01)C-lpPFo4pQ^zUjf2bPiEgsH z;KygJP&!!h>9fS{rNuc!&hZ?58`Yl^EV@+hMpy`b5a*$4%d+Wf>|9kUm*%hF5>hwz zEXa`RXLxMuqS!lq>1!eYc z@+J&Gum2>jpL^b?K!f@Q;w<3!q>*HP!a!QtuyF-%UX$E>I&3U^hh&%CqAq>f`^QUn z5d7*DeW`FSc8ftR2Q%>?Z?ofab;#PA-}B|pyJyE_`T{|cnNomMoP-R&4lO)lxiA=DgRyKp9 zWATJxx&FHmW^QR-FoDY2?BD#dYy0c~?jQW8d_musk&(oI7hSUTPwjBo;s*&LtqsJy zT+CHDTYI%^oF>D2>u^~66P`sHL@C~-WXg`2l$+r%JEv-nAm5YGgp3geFQi2niJjuk zSjHdB9jOlYfgE;6yX+PVFTeS2ThG!byZSY4TH2wz?c4z)JqxKlqD|EKE+e+Dn>$1K z-%b`Z&yy_=?(3JfpVwU_yWNyDf({Y?L>tJcDq*SiO?yhnS31$L1MxY3pmc_&HzpZ>NLE%EiW_ zx#@ME+X-zdOL}aR&upzd2)Xo3!kyDS1syCI8c2+`r%7kk1M`1+$>8bWwb!SnLp(2i z#YV4MvfXCgLSTyPA)XPKzQ&=_RD7p>#gtUMa7PoQ2ev(6_~ zvO=_pv*N%*Z=OMujgHR4>HK@F179~MhG#pVtpo~4FAJJt<9E>5KEDI(qzkNP0zx!6 zSn#Ol8R=5Wl$ip#_|roH(~F5EL{bJ}ELkv_BX1B`?)mzTFArZKnA*fKbNqH=;=UtK z*AC`ufMM%8?;rEQo_K*~kKxU0?W0PO;0?SZ*`-Ty_g#DOpqz70sL}GJGb^=VI`K`> zGr-=UgQF>H9syr*;0f1AfCQ%-Ka*nFt_<2us= z$-3S)y#55y_OYMg8Ec8D%7$f0Dxs|*;hhVog=C0EWta-kxx~icVZYu7YOK9&%YjWy z@mm+W3R?b??E7#@5dJY*VnQQ0;f!G$;+xF2=dx+pJZr=ORAAs7zq zU-hr?CWjV(x3<+Crt;j1Rs^aWN5`15q2aND{Hl}dnUwCx z&Ez(@S2I7_H{QFjys28+x7oj-;++qLSviEjsyW)%C*DT6Yur8jl<0nw@oBNTI;l~M zQni#$k9ebMou2IbDmFXdoKJc(J>}a-agHc^V>9r32eNu$C&zn!?$9E4ukjwSDwq2Sj8(g(?-uWkGj|&4{fkGq`XJ28nMup@)itbaTpHWR_7`H`r#%@=@L%YbFTcV&P6BAa2&V+q>R^ zp7o$Z7`kQM1I?J-I=m)%FGLc)+9fla7lP;#F(K{o6Vtgx&;#a5#u#w@vHaqcb3gNGtyIDUIcOe)gKAIhl$loX+HYx$6&KQ>R!`3(rEp zFQ4p--WvwZQb?i=^7Ad}Wc=!%;hO?~mw5EfWZM1%7@z(2d2lC?AkiJ>*>DrB7%W6D zAGf|fEAA-7U7Zx*wfQluvJRh7EFsuuR!409#iZ9~I14xPg0ZyhGef1MatvoFTq`_0 zcf~M~3(@x>F-5HH3zuj0#z|Jm|BPP=wda{XxlYkUV>zq}Gw<*25oO^O)pYG5*&5|& zt!l+)GMYVEw3A&!YrkZk6Xq(bWVWn1*{83z#E;dg9=n9criZ^>u1LkZkJZ??RN8+x z<(&*XNUGB1(%rCe{gColyqY8Uh`1Ht!U$3@#Aj(Xit8~0bAVJS_3DxEB_ zd^NDmDkV5D5%4#b=rAEEU!g=N^jh2E1wG+yYeX{e$aRmdf4^}sci;cHnP9Rlr~R^K zllSY;7+^^MG6dW0|jknC&)UBSwIbzb{0q{G23(rHmh}5v_74&r zbY)_~O>{h@<2E+5KP``&cfa$jQ(1FV*2kgViL2dF65TBz-}Mz$8U7Whewpx`c$ZUc zRG5ri?wWC$Qb@wENQHdShntsgV4Lbq7G}y`u5O1)ke!6ggBNa=Y{K^jXmJ)usdZH$ zb>AW1Ew`ZY8PINQ`0H{<>LnFf$sBaW_IdQ`Mc45KPWtzig7Q^K0W%-y;rwk{3DD9} z(#9&IA@ViQol_AJOR*pP_C5$DzT1Y2WvjR;&`ESz z?~C7LyG5&fYwl0~dJkJ~raV*gDJ4q2G>GeZz0|enR6l0Kv%xZV)u!6`{`@yW;e20TMT#Xd`=Pe+lqSo-kd6y;xE9E&sifUF~QM0-I7s&6p4I{)fMor1I^}ga%4n+jDMAcEy+e z6#$oW)8i%f)swW-*5kpy-8~iCr+26rkUO}$e{nFx8N6i)yedo)(8_Ij<`wu#CfTI@Nx^tw{9 zOkd~tsz0UnGW|V>y8c>ya7z{qhDwyEoJEpkg0T@2k?f@ZiTZ?X$!|0A-K8a|feq5xLn`SCT8dG8;$|wuga?zIV?h4jT)KP0T_$7R zv(2q3ziQ|-9DP;eSQ<;dIQJ>08$UwyEobWf&>mM|=2?{dLi6`@dW$wk z4*q6rtW`^<)sF-qj;4-%qX+wM$toGGoFecy(zy7qo8xl$n&I#M-ke~_={Ry+p2B~c zOk}5^vXmCEDy6+a9=oUpQ*OBFkZb>()LF#3KV)PcucO)EZo%JI_RJ?wIWElZUybLX zUEn(e;3v)<1J3c-2>Yvo zZ;<;XZ4cmobx27Khie!HkLK+HG-3fC1F9g17mls1cI<$eP_B_KpcMYEqxC?pr|x$1 zYla5b_M3Zs3K2u==*fGBllk4fdhh*#ssp+^LG%C+WDxHLHBaTr?0B&H41eMU?wK^5 zERZhSNmvQHfWSDz6&p3Usn(V44=eG_iO1uJ`uNxBV(q@8Qr8gfJ$jN&6GVkSI}2CO z2=~3pdUZz2DY0MAHqisT^b6jKrDp4J?U@~0OLNZ#XL30=l|fU;=KwLo4lO+nIc`TyJtl zxShL`Bawp__9O&G%$tm#@6S#@maJZ@=vTt00$V!s`Bpq-yGxaF-PIxm{~EoL%C0ce z%XEFv*D(uCPO|As>lC|1n4xnFNpR^HM~Nw!B|Xtt5o8;u}A{2o*8EnUt(E6=iKX!yG=U zM7Z?u-%K-yOC*y&dY`xZ;gX z5xI$)5xQ!;F)F>KXZ00EAcNVKbT}jqIt+CegYJK?EqjA{dmoDUy`A3oy2Z1D=00 zG}wtaykyuxW}w}37ZkQLkbAQm{IE=la) zs{{|o!}H0$jke0$aQE>>OgGuEH~6kw0TcMD1^;mj=wdS2M`^mF`0!AgfQpMC9aYY# zu&jK_1!7HyHOA5`vGywCt0ZX+mINk^cgSd!p;>B}NPm)c<`z|U`CUKAm}gg}Wx?NIS*iJODC@)b#DSe#@TBXXsT!dc{WP$I!R*#K{bzWT}O6 z+P+1p>we@*xcMc6TAZ!6$ArFNd8T!D!ZCeyTXO#dbzJJuA zpC3tDzFkO@;!hzCiNb$ch!0xH*OP4yc^vO=efNGN)<{%Z(yBAg*A6M=Q$1tZP$l_d z+Fh-Kzj6aLBZ?EYQuv-)&Fo^>*cDM5)KcND3dt}~U87!K8k@aLq}*K#HmrR7B7-9F ztDd5X7r`EmAKdCtbD-Ie8zIa%eE{dfa?W2gAaS5AYOx=~p8GKtxj<}vGe0D!>X=J< zoFXY%sL^fe+6S+qXYW#Sl4wA5j99yv9r9DCj6>1#Vm3w0m8%q9CppL+St+5-Xt_k5 z##dB)f?T|yh^`&#*z{rgbmF+U2IV(D7yfk2uHv+D{7R&7Pfj=O4(+2k6Of2h7dV}8 zAaJPse?)zEG#p>t_v+me1kt-hv?O|q5<-ONC2F+j8@;SvgQ!s=x`+4X z^zOQV+f6p}PcGaJFA4q*p))pt*qs7%Kt!eTbXpb2G3sgEnuS>}U6BQzVy&N=qpThd z0C@P@+shgNgLc%TItH<*e9<_O@7T`4BT{gLRm zhW{Fn-32rY)FI=mOKbbpereeU@@i*Loig+$WmonyJ^ZVS-qKIaE-4*1fHwfO122Fq zvfDBK#*9GwiUt2bLghb=3RlaQ|Gi=%oEi$0l0b_EEdRCxdfZ9UA~KEOREc(bL}Oam zIDgU17ei~^KON&#@w!WOr6d-_)hL6U9Ee`@_q&mv(v%A$3`ZRXNC2%-vRP%F{is_N z+inIWd@`l`=@F%VU_7&xAK&hCr=0L{z}^nXNv+K38be*mSY3}ds8k&OlxvsKY*NCf zRZ`vCs6j8LmS`%G_^4#CjhA@VbAZ+o5X^7VxgK(o0_-fcqxE8TBOT#dvyFt+g`Ax~ z$vGbk7$#3RJojU=AnASB??ooPBCYLP4>!fhkC@;nzs)n=lFXdBri{JVw7u;&qTFhE zX2yJvCC0xJ|K6Xs91jOfu0?`>Je`H^LS8m;M$qvx#VDYlQm69~<0S+-?HMHSH4K4t zb_W>oI{=^0+Y$7XCmtM>pWnTLuWbQktf4A_UQsG6-vmscolRYPNQ(Rg1~viBJ)4jv z7p#$EHmkXB?K9hk>Wbm5rC2d_X@{i#QDf7vMGbi~D{hbe8e$_wB~Ox>ztw6J$L~qLdYr zOdIaWJ3Rd;yxy+3l*Rrd4P2@ozsDa0n3*#Ib1)Be)3%d7$Ki$NP(jAk@@Z)}yat82 zoCPi6z58=Sbrd#09Y9@3YJzg7{J{oRSwjd_T^CRWrblD8i=0rHUk&Xzg7NZ8$ITGb zQwYYd^ao2}jOM*hekb0yLs$lVec%q>bnokwqLTuyb~3{d?Z@(@5eU^<$An9(Yh2)5N<3)GyXvr;Zb#G*tu#>qi#|%E84_`k2XBA(sqehwcfSr0`0eLmg)jHm> zG@L)tirArCMeCdz$JZB((i()^Ipg*!c=zxthfJUy<(`T9w-`Z7>}@xXcQ&S;Oyd^@ zIr8-nT&#oiw-qh?9B9TbjDJQ>O~Kw(UlTo&EJzWAS1(SKm2F1V<9K#G+QWPIxkmWW z^;-D+kD<+;5B*pJaNp04wW2Tt0`>8-uvytAF4(;BhG+;OG~UB(0~HUcm3jB3j2)!l z?b%Wv|97*r?K=LI?d+D-Nwi*iycDQ+fT;}>+IU;`QMhMSOfogRTp4-?K2y^-gNJ#< z0UU$=y*12yrXY!vyQ z@LQmmw4UG1`+4IzxgflV78PY8AF`0H9=+PVkYUCF4AbRBaZdHj@m%g552kj}g2=*xh&WsvxQC;DW}`fe1n zzX`>i&X;uq6S+AYrys^$5SvNG5X^G6Kt+dkWIROjY0je_+UQTVL&>2X#i8m_r*h{p zCXp0*MdnV2%VIU`k?p78KDWf!Ch+PgLT2J6kwy^%t8fZjpl>CE^HEn^hpWTO?1H+_ z?rz#7jT3RTN186{CFI~3*~rLsf0g{2_}cwg4BJ8M;jxJdDf=fKb!mB9Qam!ri3u^^ zDyZd9hy61t;=|zVAh`jKf*yLlN>~L$Hm-iYWoMO#9N<1H|#7kTJpiZQ*0mE=o#v zknd4d`6TR)4crE@Z_=xGp+Q|wDQbCIoAY&;r0CBT6W(ErL_K_EE3cQQcb^Xuh%Wwm za{1{D*x=)VH-9+VKffX+8WZ)I>5I5LFiL~E-JaDEGsFZ3I~l5m*ZiOBUaQHp!!WIYU!GP#z=9T@WT;0W}qdXl!^ZZ@!?i9I_?t z>_3(^E>FRxBJ1XptK`A6V6rRlt}OWbM*BQF<}*Gt_g%73GUv+-5X>W0c#J^FEWG}2 z1P9q69X=*QAB1Y=4DDja5QAV!$2tGT?f z)cVL1lcnsO2hUnw4A%!PK8mkr?|&aSx`Og&qp!dsDYe?%27`ycByFAX0lHz?uoZLC z-ajMA#^cb~6&IQ`BdF@6)5#}4ltxFL>fs%-ymD8O@P45Z`!OyH`MTMk{sKG<*U5#= zMB_mtYmp{(>E4o;9IQ=-0l!-khO_Y>?6Ko>LFnl|kJ!F8j|x8RagwS3 zcH&!gr9Ts4|E7Otcvw_Rd_Y&@uuHEYc+COzXy^X8K<`R0$6UWUzSu!tp*xLr_dd~a zlPx-oG&u<7kUBBd+y`3?0y!VnzS2ya45>rNl01kTwdb!gTI(Rrx= zWVRuG?0`qBh8_v2?^)48|B<>0U4g<6`C5CwbB5L%c*bEEbvtgA?T|T4W$ktg6Y6r= z<#jy}EztBh{cuNSjM`~Qv7(x*6Bft&zD6N7X-lX?afVJmEO@ZCxgkL3E?u@I7D8Q5 z7>7d)i=_5Dm!8R3#UCKzF54OTntQgd#C_6<>SR>{rABAGzey0P9yzLq@VAV+0gnRF z+?o_Sg%y40|BpRDIp^aQE=0FssA|_Y4MHBxr&R8OCZ!~v!x;l5b$=@#kG5V>~2^8%A^wzr8 zB|<4QX>s>8zyFx7a(pdN5KwYJRYBH30x$ze$&3T40F(=0MJnV+m(o%a)LrG4N8ub) zhbfxZKT1oKj{m``)el(fySh#JLgi(fIAKuv=ucb*ZTNLR6^T|2@bL(4)iB7}eo&yX zK+yt|U>6yUwZi_0Cw1HsR(T-2-hd%nic&G)PRodA@fY##h45%uTgb{!O6ib;*OV4& zv)$Z|H49PRaSZtJJ#=-~OGsyLy{?VuZ@&?eZPT~bqz{bG?lwgN0hWSxRh}yhVClcP7<1aflWCIoJB_n~%LyAsDuS z>!tli$@|_#izA|W!(@0AORO(*x7kiZ>3!y@>UFwCZ`?n;-_*KHbfqh~%l~2IaajG?!8pQ<#ypil+TSCV`|u)9awNoO~T%+{R$G zn}WVO3<|c#dUS7~w2%aZ+4j#fmFR{-E3e)qB~j?TxTcIQnp`h1EY#rQEGfE>utpb3T#vWzIkVOH+O ztyLMic64=lK8AP_ZI;)PazO&rP|9TI&+0stJ{u+|Un-WLG&VMd;x4%6E*C9v{Gy)c zHNsgWieu^mTmeAcXh*obLp1mMzE6SHt>qo_f6zbDT~dEk;x;1ciBJZ%#i|sIWxc_| z;hwjR)?0a)YN`EK@v0sc2ZXWuP9sozdj=t zWDQ+qzQr7ib#%i9&kxbR2JGr(TKn2)Rol7ekl6Y6A&Ic%NYNyf)@Y%bD<#gINWXac z!uMrM?PfG89L>6>J~Dnigs=@IX=}6GLal$*eX(!)9!Rq!>v1t{lJ(DV+V*vQ#A9Oe zInj@=H}2gWYl;F(s#-?e3SnD&n^-cX%bB&8G_Q{F{762IE7QMXSIEgW@rX`SkRs%4 z4u9S)`8O}|Mb`%X?ta}&20F&}^wtme)Trej=J;WfDwlqp!~!HHSBg~e_jT8#Rc|G@ z;7I0(qTWyVipCopbZTaka7HJ)>{egiN4b6!4-2il?6smi#A~K{ruyr55GmDAW$_lZ zKT{ns*`F-8$NMKND>XpP*IL=C0zH)?elDc8CAIL62Eh|SL6gL!K=k;s;l))anRga^ z3KB_vXcT-$aWcVKNXoW1@;J!;Rs-9%RWlj1B6D6ze}UfQACJ8$zi(|H$^1gb;^Hx~ z3RfyQfZNctc<_tV^x)p93{$$bfGSk$SA737I8n0gaJ2Ti0p%(I8+zlP*&t*(r1lV& ziiE_8hb-OIHurJYh)_%5!>QllABXfAq1%5?6xZDMdqxvk$mKmxxSmlNviTq$(fa8z zEr!uE@8Y5~PBD08Kjl+CdjB>s!&ai;Qm=|L9>HgTtz^g>-!UQufT2Wy31YaJh5wOX z&i)to!*f%EK=WDPh!Nbqc9NZ+Z-3nOtI3%2-GP@__{UZM^ zpa1v{FrT~mqysev1Axi_MaJ|l%}d}+9Sj&*kdiYnQo}ij4(S?x7UNyo3;Vp5lx=1v zDQhk*oA_+)HDL%6-1%O18S>oe&OmmGCcEMDTuD4Xgf%d&P!GORMs*YPqJw7_NSrnv zLsfo@d6}~(>?rCH8=a8f(RiWq<-pAT`LH1|eI-jfRopw_m{t8M1@Fr2il0~Rdmdzi zJJdXXdYd^^Ew*E5df4vSTY`!=!~@syd_Mr&G1ODpJ+cNrX8Bi1(2zdjYI7XJ<@4q3 zEn6V5!vlk_`dLR`F|z|}su1?!j0+-hX+WLud2uM~4w-j7?v`0#`^X_*kFFEX07+5J z?F-_gtT2x8AhJg|o8~)MK^Fcx@M-LyyBbv6mX{;4-Q52&6 zC$72%*a*K?!s28b`vR))FK6#lADKFW)s_?TA;c2*5;D)C>apZmd=7hPsDCR*_IUR# z6(mI&e&O`D=3XO2EResdT*IId{RyaDSxt?*1vl~3x`pUDj$PF#^8sjLK)L*a)jr!z z;|;;!!zF>f4K7HGqDm;tWvQPNc2DIuuxcnCWhpV+m3?p{a5xR6Tr7A&)w}?^6Q0!2tkcjbrg23OpDs1)F6!$5T9b3eWH~z&}wO%9;I>|Jw0((Rx~~ zMPym^+W$GlIl5Y4zTcAX@W%=4fLn9chSkp&ep#^kOHfs*4kYY zBcK4am9Ahgx+QJRB8||~Dpzo$2bu-{h>NRMXUL>>O)Sscv zRt_9rr?aU(e|PqK@i9wHGhw!M4*|s$BX?R=fggv3hm6*At6sLhTo<>S6dZ>PfbO5b;|hsCY-G*jH5|^ zw7?dp5&aOwB_b^NI?Q<00IUL4o8A6#7jN@Q}igMWJ`#L#tp| z;cSy2v?@IQAZ0lPn7awoXzwFBNdE*>hWbn2=i*WQ1xvmIPGk8&4bCdGd!|L zoIlfM?(~9y;;Al>!#Qw`feb!kc@4UYB>CR3Iv>D)PcNz zBFtCLm-paO`Y{}MC=QFe1ed~zXQ`ehk1`M;2Vydz4W(<>HR0%lNxP7$L(=w;3&lpw zesvAt%^;lnEsx3|#>lc`I*fqnx6rXP<314J#sEUZzXL#tlt>JJ%ceV=fCO(utWLRxo*rumc`GOO;lbN{v<#(S`Mij<{XuF}rV)im@CU!&X zl-Xnk|Ji!0n8!%`Sww_PgGr3x7E;J-g;JiHizzmrJX{TOEhdd%%wfsVvF2xwo7`?+ zB41}vUe&F|PFewE0E)a`6wy6%qW6q*jKQ35nS90Z2T=Rco_g7}v zI^dW`R>5~3ky`B0LKH8~MJ;t9n!i-~ zv1MmN_k=`Mdbc%R8OjUoX*|X^IVD*W{s2x~x2VYcUg@Ufods z%C>sbyf5ul^ z=^H#KkEARu$eMBW4-}OFP`($)9sEoC5R@~>nqpO8HL9Kf<*eMYfe+P6bq7YeGsh)q zIPT}Y_KWLfp&oACrO@!*piM)o*T5Q-{pC0*;EIr)vvauhyCd@@bZD(9sV&DJ-^=! zz*yF(J2X-fG(Dw#8Wj~WgV^S82ctBTD|EdiXOaG%z42QHa>9I4)IG9Q*6VoRq67Wf z?t~ILp`_jJMB$Iq#nQMuxjs^VpBch)H=v06DMi*2$f>(xMOX-&VBuRX<}g>}IdnqY5feA2 zimbtk#yX@VwNc;AI&!n{UwUCGe*j-OxMN&nZ0QXog-CY4kSSUtUI3_*?1}SK=MRE) z=M1dMY&4AYwzcP=Jlq|~anr9i6Z|A6JcY-=oN0Qw$?dO0Rx_pBXBMVnSE9LW(kt4# zkEP{zpw{G+ZrTKp(}I_dDG^i0xv#*VC1l1pLp}fN?am9O4_`@lTk9QgF|2~`TM)zB z6h6#{QWj*zmCXBdz3$4GYWWD(YM6qNalJ@1OH@~@-PUweY4OIU<%cMG)pfB>k7OfV zUjNBqGMEQjv$S;t<5_?dUROnqeyN)h^dR;BaPn2i7HI)dI=Vfk3wO1=#@Hnx`2n=Td$=`&_0HX2j=>K{&@Fh!9fAIel zzw`k>D@b;%qb-}`|RYP=Sk)7AA$;z6z z!+t%}Zu;q}d@rI3q(wjOaxcNv1UViirsQE zE-})fY}gWFH2~+Y9X<3@^zc=Z8#j{mDqmMdEs{PvC81F%@yjWYqSW~JC~s=!Ygjqg zAi<#m;dm^LyZ&p>7ERbde4?1N6vYP}>XzI)kYxcR>d{>W%pD=6MccM*-4e*UJLqCi z+VNcK=vmW?7pJ16@27b4>Zz!eB9NgKR~`P@lgL(0idL11(!Ah$%0_oQvWHbYWl*5g zSK|uBA~GJCvOeUjxq8~p@#rzkMS=Ep%OWg2u(c z*=3U&o4v%t5n&#ar~lpx+dk7;e;9Z+1*t<&xHuYOXP-niSrJ-eiKCI`NgsU8eDKI0 z&xy`oB_vO*6~vJ_h|DU0`}f_GEu&W``uCS&N~VtAGk7h{8~{w;L4x2rWQtUm5$-6& zI+byMUN{&3hR*=XY)t}y>0nzThq8s&yB3!kMATEDX84?LI@8bQKngMxh}xq<3hYN9 zrbv|7ZRzcymdkgqF8oOX_VqPqe9>BmRiKiceL|y?Vl=@>ET4N)BQqd#mMFF`FEh zGgIp)^17ch;?S>rb6!I;~h)T?~p5T52#k z2uFIpwYB2~7o8Uo?rdB4%aq&o4WyoM!gOOFr~qKPMGK*wR=wJI4R6bw38&MyDJDL{ zqDQ6#iYQ@IA&w_{r}Z{yD7VRmKFRU6H(TsO!9HUw<%8pZw1Bo}j=#Q|ev%%r}~ooku+e^fmQqDXkJK03(_kl1%t{{HQ4 zgC>N>)t8Fq)P{(G>MRVTF*$FBdOiv3zO%XNM0=_IXASs z+SFfh?Jiqtbym3-_hX+xuEV(N-9m5ey*voVY_Ex_TM!1HmqG|%)x_J-^q5q(s$NRC zj`#nNzyUr;=2^eTmv{#0a=7SEJUo9@q<5sk!K`{0cCvdKC_>f(B~{d7VxCZ)daO4$ zzfPAlxeEXuj*eUu*SLu_ChQ@h%BHS`_?zzf{GjIhK7Eb4JqNz_6TX~^;iA=F#M#Wu z7?F(*J&`n%q&euPH24DI3K&aD(UG`8FAobET(JOgI9fQOc0b1+cStTPry_ z+(y$f{~W0zKts0{tR{WQjX|0;wEM&N4`10Aux0%&ev!y?g5B8~ZlHYfja8r~a|XU~ zB^(Xcgye=uw?9A_g@Fu4rttz1Ag-kaY5)w%e)5}?%ef3-N^$2ass}L0jL6ZdW#QW( z0O~Pb5g@$jpuYm$1_0d9DB<0-%XAkmA-0Se{_F#mU;uk z(@E{~ScgJ7mI$tE$m+_TrmyYID!-LyzsOzOcH{cE`GMjlHOS8F-zWSVjuI%>01lIW zK#BtS@pUmB)#1CB|Nh}a^Z)aWYoFM&^HbS<@4UIijOZ+}2YAvfoS_=)zuG={+oGko z0H%J9#yX4g!;mOM1$AXcY%boFw8u`CXB|x=OVznaFzXUV+#4pBkR_sVmJ~Sr<)wHV z>H+0P=w0G>cM_8>-!j>as_Ily5RKMH(pXTq4&sU`wiQqjbjZtjhAIFRR}o7p$xRW{ zJPed*swxMbczZHlgQ0xnYDWY9Z3+22g>?Cxvq$~r$J~TCM+j_v*k>I64y-%a&}Bh+ zN8LsM-!%>lvQw+*$yBT`L}$gi`jlvOrOwfH0xx)UI?@?-KPd zBC7=4(LZ;F@3josYNiqc&4P5dE?nnJ^$OG$qKKb}b${f+mK#14(3l=3Dau!Asx zbBu{R1HPn)ytyVkUjHxv5fT@daWf5rEWd;ko!w>lY|d%s@h6}M0KV_Erm9dC;-q2YX(|>$7`myx4 z5K#i@anZ=*D~dpeYKENbf2aT0fSEEpFlI2jcNMFVlqm(Y!~8eQe^pHlN8YuPUU)5K zbh#9b{n)iK7QxTme8rTe#OjAurHRzYBn!=qetV^|1#n&sT&@@E$VCakN(8>^sSX5I4<{+hsh(c*cVy~1 zaMw1Moj?&5U9{Tev;Q!y&*b6eC~Vp%yw5NJZyZU~i!rABJ~DvpB}h$s!}Z{S$UrUKf}CjVJ`*+990Zc1K7~u5!F^CPekX@g-1|<=LWvw4t0($vCh(aofXrKe)vEKP@RD@}ZWMw#p zEh?&{@dL6uEK5kkE|T#}$ayo(dpHTW-wG>AZ`?)pa-E`KYB#+3a!AnhoM~4A2R_SX zYcRf|KAZ1RCEdk4$mXsxXs$v$LG_C5Hsh4{@ue=Wy$!@TU#R@ur4!>h;jUq)?b>M1 zMt@()K<9&52{x}7$$=2X^w@IS+G|>JW5w9W^_1e*>tLJ8E185UD>c2rmkq&+gdDQ` z;E}5@$uF5Hfwtq~tO&lT>bxcMty6eZVFF^4I~iZj9`;ZvsF>U|;&f*CC=Uo`2F zi9#yxfCEjB>Jj13XfjpX`fef>)I*1K0pp)l71}SfXjFj2nm4FxTuH@|rpd#U>5-}HVE8PQBJRUNVdl%NztKV#1X|C;9 zQi*;HE$TPk{5^FO&@z^cpV3XS0JO8x9Z0y_>=~YtW?Kv^-D@uF(?8{| zSx3Z{1`$Xj-XWnCel&J6?As*c50mQNTw=5}qko#fxIG z=-9Cp23zlEkSUID!=pza-lNN5wB!E2LqXG1rs$t!4(aCg^&&kpZE$A@%u=u_fN^>o z0oTU@{8C}b>nS_I`#3JQ{lb3pEAIQ5o>9jklp;Ux>EdJFU)O(La%56jqD2(|X;KeH zCLde!+-TSmhpCi<%#7!V4wQ5Xf-jQ8GV;;89`9z58x><=WiZx51v9JkOb(tTmYt~Rf53zJH^d~BlKUUjRzeUl5I*@Y{ktT(4v zca21&zzGQr88TAX?*AQkagS)wsWTonn0kC*itxiSb{TI_daaUeYLZ2!Q*y z0<*5I*AScNKnhdENAVYXOuNn|%cD`x@W%!E%=}qfwm0=m6@=X1k)#i~vRos334~@$9fEa-D8HM1j$}Q?f9{-B$Ti0w_l@Mn7 zC`$5y-Xm>^eF$F6R8y)pM3Bo1=k(Q^D1pVi=r--^Q?PWQpsp9OP6V0*pJTS(jRa1j12+?B zjT1*)6^P{(i`4)rlJ}*U-=4l%jl=v3Nh?@f)ABRv$4k23RdaR8((~H+v7Kyeel|rM zS{W7LxIQ=8BPF-&dZaKE$BR1Umc}_ldL`Qr*yCFfRXWhbhG6t#(xs@wmS0EBTg7jH zuQ0^gL90K+b?~aJ-c70PU`|eny2oe2Nq-S#HKYOzbIB}{8{&mWxup_d_pl3xFxR%fPxM^n+7w@g960N9 zU3;V1`J}vs?T;-8{u9380T}_^R)EY%B~BOM*-ihc;aw8SqYT`Onx(5t&h_%#R z07D+cjuGd&7XO}q=-U?Rvj98i>9M|ZF7it21u*nUWFIT992qr`z+xp|YcULvO!guj z64@GN06|renUxBQL_?CqW10my0D@5)!qtjsrbuvcnw&tcGmu@PMX$eSHee>+ZN2k| zHAFrNCL(b?{{xxMf6oPTT-W1GrR&9V3rBD#&+%}dsXaYGCZH2(B5~0#x^FXzGN)g@ zVTr_4&XLw}wHH$T4>4Sz!< z8=qhlv+RAhl_1UCe9iG-@@&ur!OE`LPK>p!zoO+A7IZHBC-a9>@u#@5?2pyR{#H44 zc4A;8D|fT3j`kS5I19Ik&?xqUqeewU$yR5*&N%sc_5#}k zeG&Z-L(PBRqG&ga8=XoUk9aBRV4)W#CKC@9RBm-37qDHl>i{~|799_nDjY~Xd`JcL^m1|2*06F8qc_5dMi&vr^$1^>@<=ZK zAs68-2^f3@a>Qq5ex34B{cUI&tZB==Ko`7gc+Pr=9Pb z){Xq7@Zr|GcV4GI+wPttqrh-0EG?!Z`7a>h%-0IC8>*uQmOg(%>R#h!x-#Fj#!^0K7-Lc`UN1-EVCf+6xt1?P2T3XTd1|$QSA;l zU6E~@jz`K`dUm!_Sv*$LJJ(PkKBO>_=dSlVZ1Ix?yEk+`d0&H_Rf`8#Y^JCBXy-VS zSO;_L7K9CF7I`!+Jd(YySIuw^e?uQ<6*Cq>*T|ZkyUWZHC`^3IV;DSQS48Lr|tBd^u37AKsVz=Dmu#XaE5}4cG*h5&##64>In0d8!%b;bszgq&`L-T;c)cHh^Y%l z2azzb1F*{UP}t<#^>4qukzGN=_a#z*5{72Hh_qASbT7`*%oa`r)K1nwo#9HlOv5kx zP}@~$k~=mrHYL0}=wSfPLpqY%O*~QRYt@)Ua%sr=D;Br?8Jk*DLe39Y*$17rGTD*f zUA+so`K$HiFEO_MiGm)pDS8I{LYs;*3+3O``QqDyXm^`+BPbq?W&nabb;qS_wwYfm z8P%t3`}~jswg!=xN&3wb^8`ZdJX6$%Ln3+!YO?5uYb`q*4?CEky`-^d~x% z-;0SJ`EA~#CY^XbxIkE01Qa6A2KQSgV zO+SB8HBJHAX^MP%JV5k+Abi7=3fL59kb|Ki;bGb*4y?CB%;NkehTHtPxp?3Cpdb8w zsJAWiBTtNKkZNcJHJo)n&w6*Z%N=4V@M;$R0Q8OX8rV^bCv47or6!vM#D-uY-eg#D zc|C}Hw#kH9w&ydMG0nbRQgo(-l;dz6_=a78PbKEm86M=4+26^$$6;?7PB!Y)Z{E$; zlG_swE{N=}zu)BhEWhg4>Ovc7!#e7FlmXWy@iLC~{*-PwIFn1xlUF-pR=q6t)yBK% z+A4fMG%zbp*r1;^bo4hCb~obkdjEco2v+12P27ZfMxmD?x?Xj5u{hSszaSRqpAe1P z`FPY+;;Zzbg-ESz-n7{yoikb|;+PGziIc0Dn&@AFvBZpKzxpZ$y9)SAwD<1aR)gty zjQc5%mr+TIm-ez4YlK3B@Q-IDzb9BLhcd^qi|m)kq+id#1zyrf@AUNX&H&1xZ}mO% z#7S?K;#Ykw>s$MUOsdT9DXOY}V_G*@vUuBbBrd%J5V|dOn{Yr`yTr(pD#a8IWE9gP zGGo))`^9RZWUR|LWz8j}l^Qv|%~Z_m$0E1$e&d_bPPAFOfxCPHmLsRSiA?J9V*p)3 zB)QEG1CoK(_e$l_ni_?6y$Iq&>w%HeOi%~OYHNLL!#m=GFd``D;wc;Zp-3UjYCv$5 z02IVAFfqzP>4bU)QPffzpi}=YOIw=Hf_DNyi7(HE+XT@m=Eas>`*xJ0>|{k)uF!9j zgAmE+tvy&{N>>Wp2q(2hYBGF~#f$z@%BH327&QhyL{OQOEq3XOJP$_2BxebNi2U$Snp8x@ANF%$pbaM1>~$A^kL-)2(t!IT z{A@zVmdY)1y7p=hrr!F6McdK76bY2%Xtc zk6$z?u#hFPK$_3G_(!5SQiYDMjwG4{ew&yiioeff%(LE~kmUy)w7-1K@GkcXzVuEjwJ5z&KeSKUwcXI3b?6S)4`H_Tg3b$PA7lKp(& znxc6BR0Lb*A&GWvAhC{fHM<*b=%Y48KK;lBL#l1%L$q742bsKPr#|o?<&p`1XHaVo zWs`jHb!;WW=6E=YY)-0&idvWMzL967w-R-EJuAVH7tej8AeYCf)6|*XY}vhYNW6oq zyN;4wB(8gk(mM`fPToS9E8GeU)MT#b!Qhgqt~__NXen7a&G9K&vEWg zZX814hkI!`FY$3x0stW&f4{JP)nEq#d2_)!z%JMajhrl_QukwMprDv)9APK+nRHY+ zJx18i-v6to8dk=CbfSGqxLz`?@X)TI1D9AblD$Iip{_Rw<+OV}5Ik^sTvt$EQiZiS z^;H-G?q2W+77^od&b}iVP|WJRycz=`#sNUV&e7@T?$I5DO3QKX{*n?~<>u5E8&Cp) zD11A#bO$!mMeNl7k%KlcZpUZ!kbpM-fMpyOuvxJi20K9 zWuMQ~W%<*xs`0@NpaCL>?Ne#z?Ig?At?~6V-2v1iD|zwlJEOhr9IAR#9~*){B5Pb@ zigZXXD8F)ODfMlqEr3m)M$^bsy6*MZ)&{ZHHMbVonB5g=x3|$+05^wxH64GlaAvX$h^-*kV}|`us$S4r+5FHFso{l6Qi25+xGR!KYa<%uJ_~&ct{I@)J=0(>& z)d`0j!DIAhkl3K8%2V_6$RoT7w+l>E_Wrd+&|%%gr#jR!2wonD+=-dphGTD}n5bn# zpp@;B0p@(2{}yVo&!!!7?ovXbYvL0OIZ7 z9S}kbd=Mb&sln$t{pS0}H>fD0s2NHdAd&Qil~tJZ<-^p@S0el-Ki)1IPsBF6;ISIe z3p)I}ME93v%Zb%`vGdmyEUkCC8#Re@xyVudhFyf?$4oWV^}Pe5n|AifEk~}-v@|`N^k!z0fP&z6Sq5_X zD``g7B4Hd_L+~C>B4Otm&jd*^>k3vS&5Lf@r;mOi6fH|T{=!rdd|D1aPw8J-CK<g2#qr*(+*(;g5;! z%O7&2``_vr)G*09<6kgRtCGA=&ikafD|>uNBzTf(^I&hzRFUNg!?C!-+YXCv^w*(> zUANb2b9K9^V}NhVZ5awZK>y9`k%S@k+V5niJP93yYFn~j$#CjCk4K(0QT{(5eDmi(-+RvZlvh6uIB=I1h zl~|70XV%N7-yUK$_(=Ox-rw(|PIl(&^0Oi))fJuRbHfT?zJ2DL##bVrf6k{)HHibG z;b>EL_ruknG+gjz$*0du86%x%s=$bNSCV_qWcLs}?%O&UVigu9`OR99!$1z9RPAIp z(%9Z$EEmz`c`~e+l~oXRq)y%bY}3{y^BdOf+)ev#VPfSogEzt@iIflS+lgHtoeNfV z5&KQ}+XB@M^#KA{-3bqrsGTYp#%-iK_DF}_-_C1zP3K3Cg^==5arCZS1FMKqT&W`u zxk=4{X&tHACDGD!s9K$Djy*@Dcp2afS_HX{Wi)hJ$IxI1&*ph(BFlkNPL=e@iU0OZ zMMt!Gbt~_H4FGh*g-{^3WpjH9BG5&z+h``R6pA-D5*mzbe(nmh`zGl;Xkp5tCC-iG z{xcp?RY6v;cnqu_0D9>~Z{!gRY)=P_t6pXdn6)4Tc_px>=-OaV*t}2AT3`nW$bIn} zr90~q3WlAPBMDeid!Tn46OQnp1ltn3n$;?~lh{^V{7R0oLaQsw=dX5upvUxJ9Bj_G z@QD^dIAZDQ`)>BZoT_2GZqrZA+sGZWe`?B?g#X|4NKJ%fA!~eo`+p1nI?e@pz`|o9 zl}2LnC~Zg;NLsK`RM%l==mfd&ckpU1o9k+>F|wqjE?BVHwtTFOgUs_84($inb~u!Lup2RS3ansYR;ZRw`=X!PcLPOCRtcBVVq#w6RQA z?Yudca{Yq*NFm+`k4?H;3QV(jB_zJxdvjZ}^}yL|Ov5Pia-+WZu_t<(MasB#3!3{X z5F!+4wp;pEaFV z?i?Chl-+-JdcGxp*KVBmxjgpQ0{w)qm}}2zXnFbjD!;|Hl7+8;V*oG{=>gWW$g)*( zZE#0#peNn|f?8t_Y*QVGpLMi3-&!)_WLterwp(z}Z{#m}UqZ_EaLh=s@~&cvhn#VmgyaarPeyx3+pjiJ zrGDaCk&2Mz1uhInbm>``O>O9{tdUKd+JM`@6>X{mh?D1m(T){KVA%)m>towR%M_%h zAi~o^mYM01U{%V@)gTp{`(J=WTUot)D|o*!hS}Gsp$0}9iL*jQU~Q|`Rinw>dx}^_c!m<5k)KiQ}-XcJY~jg;rXeLD4E2Vc#cJ)%3O#Y zr)%*|nuwue>ZHCedjmNDS!P^AFboVlQRqKKKn)gNO;ud;hM8Y9H~G!<+hHUA61jrv z<)!h{Gs&d8p|o>_(tGD)odp3Ne}~r2<&-D{0Q)yUaZCOG{`H>xjb5>v2Fdc}rzYvm z2!CyeR00&_@@GyMOVEYvyw^IwtxGW85rxYBJuCw5*~Qok;Z%5PJKQ1U?>h0o^yX#qGx zXa4T(U+u_OBoU$jUYv920nLYuSQ|*_ZQ`}{SN{emE##d^z3vlmnb>lzK6K8%#x2*3 zM`aIR?Zp9fAmmF3sYsqYd4GA*P|X!+?^O`vfRu)U(hEru zz~{UlWhHied}__zb0$Rx zd177WcfHAYg2G0^(sHm;fs25&ZF0bYiDd<1w8+%gz(er2f5p7?B_G^Z6?fd`1H#SM zCwM!zMc92!5Z`_%>ia*vs;!&hd|r_A1>D=Po5qwQ$DY0Ru6K|w_SNHMo3-^29+xNT zp6wj(Dq34@wGXScsdF^FpLcU_<{zYq7Ia)Gv2osn3Viu>{sfTocSy=A07lg+)Zeok z$@QE6Jc)pAVGPjm2@D$(oiEfat6GI(Xt-_>U=9J1gV+KO_Q{dWIi6SWmSUr`jtdZ- z_5aGc5^$*3_B{wmND>l?BuR55git6gmLuYem`+5pO!jSTNt8WFwj4_oN%n}Lk|o(g z)*1Vr8S7y1e|}Rs-}(M?UCz}xM>Frdzh}Ac`+1)CW!}h!L2VO6|LD9&u>ggTKT!~c z^lw9Fx3#oUtz6AxboI_MVdgVNe5*H}@p0)1x9&@DF3K8LxN&j)@8g9jvx+nC3d7bl zQA(PcmT_=!q`FF{$w8E7b?mced-!gv6!bjo@Aht9^T?Il!^iOIkG~*(N zDCBqy=0u#`2+T=(a!@9}^`Ydgl%arZjoNJ7WgLtNGb3ZdcD_kBg<#Sb=Fc&m=f&W_ zgcJ^#waA8Q7R*;_`=VD)gcrcigP2ecGbPj?zD-s4-I$pypAY&|G&ME7E><5@=HlXt zIyMCTU*k5@V~H0PjMpYLy>!&^@@v@@nfA?V;gN^!{n*Bv+$w;V3>EMq^R9A>;Y z$+VvuTT?X|Qa=2^emFWSZ&qmA-$H*0960>%SNiY^gCUhYtGDWMil2HD zq7ls8dS5?V1eOc^IC03S7&`MGfXW-jZ6}Ew*kF)|t7VXguk8@^tR?t(CG1iS;{9>< zW`9o_g?L%`U{kOA{oc`UMJ*3`h;7H59>dH5GB!g!0{2r@!X%`n?PHo42;*Rf5KHtt z5q`n%Yg?Mdg4nVK9*&dwpOQ4r1*QQ<~mRBE3NBK-{Ewy9%OHa+g+8KoWscvWKIxGrt9pk;Yl7DXoc$i~Ip8g2Cvq z5Dp9j9IO8*%q1g}Npw_ZgOicWaHm9|fo!BC>v9C9*FK^k@u_)`&r^S#v#{Ch8`-?Y zNd~x>Y?^{2@k4*ThcXhn6lg*y(O-vwVu3W=LkY|lyN#ltOgT>n(@D2aom&0&P(J4L z3JHss^y+XvJxVWl_4{T*_ChyAQwVGP2t>D7){*4K|O*T zB#^^zZVd+(cs{d@R~$M}A{*1Iv;Csj{j}u;&ya`zeocft-ErgI<$ZyhF7*Qy%Fa_7 z!(EEX95s4=NuUuMF(PLiWbdHb0g60Ia)#UIIPlky00((Em60@ywzeY(UhmRWb{~84 zHShEDLla73g*!Hv2`bvMdx|4M_rRb*l@1LBoPtX$q7aKC!&4}Q(R5Fu9!=ba{!)E9 zm_x{Yt7xWT#oM-I*z>kJ@_xigdL}Xi@qfLpys56Pc0^THj6at!Et&mRmtnVZ!Q)3* zlV~b!2xuD#0#-8$4?FyGj1sC#u*q$-X4c$h_jji^4)h%H)yYTh>EJkqJ#3tFM>sri zDN>X=``@p=1KibAkNV^_)7~87?cW$K&X^?sxIliaj9y_V$?8YMthb9;yjWOnkENa`$`N>kJIUDY_ zTF2b4W5{B!h5jIa8)p-^&RBv?WBgCx$W>}Ak~@r`uJRv?!v#0?X4(_wYm09z2AG4 z_u%85#Z68T=!*{A8+B&8-3K3h8a5bH&J%~6co78`2SB2YTKtfK6dMU}CR`0O0nUbj z0!D5NOm#y5VEI0N0sl2MP1bsLt;D~c8FfMIen8g=seiwm-|HWlkDA)dp^PXlCs99V zzpu?N_B#He712!!QFyDp3R4UINPlHBu^bBT#{s%Bz=eng{QWR^vjZALz%jYavn-Rj zSY}g;UNo5Zv^Na5RV3O4_F85h60LoD;XZZAv!*t?@#%3m=9mK~4K4^8F*oJmf5yk% zh;6j-bLiIOzG;2vXBme!;9%^BWiN}N!z<43VhKGcR-U@NhXF;$faLmry_628Z0l17 zzPpIFvpL*kLwPOv7Y&E7{_6OKhA`6zI0}-&iArK3Lu3cnTtvD=A^kvDjQP^DeyhQ} zKE-10r6*e6^3rt z&BZBGy7wxahtuofiXu8V&nd>eKr*8J67^cm8)npA^ZI|s!m4kdgdb&VTUj-%Y|d8u zsH}g>PKvO^ZkC0@((;>24!ZnGI1psxkPe<2F7tR*q*WcNTZmC^g% zWg&{~Ag{;Pboa(GU$pIr(TRE5k-%{v@#=u|zb!>-k^a@e;v`EVe~2adjiGX-Fm`OJG9QJ4Tq&l|hLJvmR$ZeRtKR1ZZ) z+4qE^YKmVb#uw~*n60s3@ zMvpA|^Q3OWaOwV5oYm%+y2x3k|Ai#!rhg-6DxgT~SbQO+b9ui)(a@;Qr>5T30P`xE zGWb(?bR$kZ_&y1Y${kS>paDcX2pT|YwwKAlL3(h&0{_j+P#t8+ec?{j__*d0R8bIX zW74W#bnK4s?B>$8gX-+1GgFV%-PcO59SUc}A1+o%l|UwBS`HRHLAp}_ooF!kBcB2B zmRKJ9vqz=sDY%%b4g6l|!6NcUPdHy84M&n@59kbe8kQ}%zA;$qO8?)n2KlqzY-XC^K3oG(gu z6~W>m$P}UbE-SCU-|fWzgZ-|-yv>O0!`_C4o z(@_uk+j#Cqz;S#6#|EcVg!7}<`&aruMb6Uy|Ghsfyf&2Km0_o`sbXX6xn9S=dHH$i z467~&LUv&^AIt^x7C@J|wEQ3`M0LwTvZi)~Z7T${^J09ykm{#UIOnK!a(rE?jAYs^ z*Z7^E)^47|f1@K~Jczs{?Om#}jbTMC7nzXmZ}nqNw`uk+g7`X6hpZhHJ^%Q+9?>s{ zLJTg9U8^n49bU})%V(P7K1EClV zZAA}I$U5P$tWkf0B?|wPHtR}jU&oeTTB@m7o3of3nqrSI!_;rXOqy*_GP#@i6}2Pc zZKP26^w6-2D3vegGpv!u5#(4TAa>xG^QRGjX+~>~9aW_cJ%${AEnds$4KI00994PG z=6^H%>VsAk@ke)3&gv(Vj2@R>s(nwJoR7HZ@UKBg8lrcmQ=* zWi4B2SiJTW4peBs9#)jye`vrUfVj*Vkz<4^UteHxh?h7Y1TB9Ek7FjK0w~^*8%o30 z5bvRO*BOBH77C!LKTwqZ5H;H=ji{mkz6vAmuBHEt98!x800F;z`LY@v9liM8c2TEj zeQs&*+;GGD&rcvIf%`$YgHy)(t=)*$E5!I2KZtlk9UOV!aBT4VNU)tY$s`)<b)uPa2Oz)h#@f8|jP2NFuhLcqQyumeZNYS%W z2T;YeUk46acmk;)YS2+Xd)9Si4bOzdY7G~Pg>$Oz2_jrRi+`z4^r5T*t}5C&F4ri_ zPD(uhIFg{wn#eB>W7Pp+#}ObTQ_t`dT0&}oYqok!P=qA+g6zYo0lj}br@lEh6~~H7 z<0@&e{5O@jd2{meQ3;7DW|Z|8p)ad_eHkjf_H7yFHIhleCxbTg`C(T)SSn|Cl3`9G z{Q+$f@GUarC*wr|+ya204n?iCtrsp4-b@?|=Th~sl))ddBt7OJoYMMHic^7dZMY3k zR52@LstP$=>0dkqlBPbtfFsJACn!n57wsX<5mlI47s$%wqau-){r?vm^>{#geZ)9p z_T5Upnoi$BfcbX@1nR&scDHu2bcV{FOAA4N9 zws%%^`S@d{xy@B73twEIXT*2c$E9eYa`(92k{c=|<%de?k*WA$xVj6Oibvk%o{h7u zlM_HiW&)h-a4R*6w=#SNNj->x+NDOhYtG#gkU#0zT%4g%ME(~hLH@{|@DD<@RS_JADA6$--eSH&C4HVF zrVe9Ni@6U%+PhU1=*>MZJys7&b0cofyJpmyu)Hz%!J(C& zNGV?eNsA9Syfs-9-3Gk&gW7`#2T1+xDRO59By1}4PTFAr&Jv`YRutvQ4xm>Re|Ej; zz5D~yud2LJZ>4%cBfYHruTL)jr$iT@jO60bos5#0q$ zzD0w3Mafi^o=UklkNez%CL=SZu4^oE?iw8bnxf9THxC z(H==5T)q+stRCN@VXVZ*T-TjD{7R<8x{)D5`^6Fb|Vn)+sz8t$Wd&&1fa z)8J8q=I-Nk!k5nEAHC^&HzxS{{hXKN-3~ez=vj8X8N6E|Zm4^fGiM~PbmoWAd(YB} zK0;29UY1Kwrl(7B7WW_b4@pO9S{%OqICcf^<8#Q5kAlM|&Dw4soU+#rvupbCJYRC< zhkTRwss{rKUX_dKYm|Yn7Ypkudfk3RnMq8Je}7aO@xvD_Z*DC^tY_~sVxyGt3G~o! z+~UMwD|u#!)>`BLVWXTE#=r7K$2ONxxi^aVvYsTXv{)+%pxE{huKFS z;v)%s_%m7L4EL*rIur3X!{byHP}Z=72fEWNc8DDo&8W&^G=%1 z#)ggIU*Xu=S>+o&qruHCIfN2DmAj_&A%rIWqupSmMk2zP(37KM5j#;J?0=2d)0(vkMw z2+3Km&C{FA{ShG)?u+jFAh(BfF3`qy2PH+VC{B@L0PlC+67yz5t;m1@AE{PE-a+Y8 zF)sC%)wW9s?^pDc8qBia4kxA&98YNGTwT4rcww2FY}zS-<5HyL`J$D~C1P75nQ(On zjrF7zJ{53ub#s#%gmSs}=e2+TAh(+|6Hc+c5D6C_r6tpy%8dHGm&7owOGpD z@#kig8|y37)WVF3+qQ`wHeFU%ry?Y=3`soX7i3eX+Nb$`P4O*K+_R!w3g-vQZ!;6# zu;D}kZD9LnnedS;0xbuP%lRo~EQ#a36{3@tQ%-WWi9gcWxZ=hQ(TwQEzVCbIQa6@y zD;E`KyvhQe*SWMkxF}oYsaq*0o%|_y`8++|TvcP=tSG!CmqM8vx~Ed^M6w7QWrB&l zYi_W77+H*p9hxNIeblKyS8LyhbTuz~7yYlVfKwDbQT=^w3O5zr(a{pwt(R<8KY3Mx z4x^B4CPl0n3d)8h(u_==O98ffmT}|w=WZtNG6rwWs-)3$$ui|>KJEuTFs10FyN02#>X`eY{Qw*p5I5cA|u!kdi-!i_6Rsd zOYUycIW*}79VX8oD@jbc8ob}{&q$FA+*Sq3tHx|w8%{W({-l!k@{N$(3gfo9xt4AP zkF3$Gu%zSJQQG6YER+-hT=uW^X4?@jvv)12SH=kD6;9B;2iTf3uzJmu~>!3{Hk_h_J{-J)yYCz*Uk)uNM6x}-p!1yb^8jQGg+hP zWsG`nT4ouA30yPMP|23(9tG25$G7{U70o@hm~kS~3OeH|aD9xgP&gaTsxrogh!G^2 zd8e0Ht#6Z4T7Da-ycsjk^9i?{UjDpuxv!;S!$;NWZIy=gdH4-Cj_e^D;ymp;%Q@6` z+^OUd$ZJ?Q>$QU<~L!1N9pThpnWVXWJ@Ygwt{b8J1Zgb==Qo)+I= z&6UOf=?uon$|xHf~Tq4F>RT>t&BlSCfg zQ#a!+sqlXoFiZ3pFh_n$3ZFnZ+4OX><48zYzZ?2_bIW#$USGk)hsFxKXW!MQs^wak z-}}dmIv+Zyvif-g8igZkGRca(ft1y+GGz1Vuaz{P0{*H~Tm*cUs@ zh(APhDGu6Bz4|phBtG^rjBO)nL>MzpT8&=GI(*;HW69b{v9Y~f@WKhPQuPO4y+}^Ur z@Oq{V>Zxrwele#M5&RpL#CrOTba4|E4wuHM*8)B2#_8_k>xpy-T0>|eu8zX1$7e6kx_!Q5J}41pio zQ`I<``l*M8Z$7VmS1an~M{HxChE1pqk^kW`c{?Q_Ojd@_qAJ=r|2)t8Lv9P<`qoyX zL>}{+O_vw44TYiS6FeQs7d_smE2r?0&M8tLF+esqSFO2I3AT(MX51*`C538^KVzZf zu?Xl^68^}Y|GZv(QLvlxcc84c6lt~JoEGcinx%G=UT`KY(-SUK#!M42^>mm8h(^d0 zf&@z`tHcKHIfc`Ix?9;W%EkNoLh;_M^;Cu&s^;~~A64%scaPRiT@@RjiIe91aX-w@ z7v24#*pmSgVielLH!W?e7eK|_vyhh6;Bm1eJ`2JM6KgzGExE*qHR{wizCQM{HMO`f z0BmI}0%~+g#r|09$_fX>Rgh( z^?Lj>uUViq{_9%Li|4FZ{e+zrCSKyhK4xH(-1vvSknY1DQV!E^JU?Ya3^pC;DfB}> zqQKVkJ2Bx}B&b+pBo@2mw- zpFAiV$4YFiz*iJfZt2Z7*pt2cjaz%k79+1niougtQx%c-JvrFpRMk<-j$h!$A45Xu zi$EJux+J+&Gr)hAP9DO@s&xKPP6bE;pv{Q(mk=vtMiwKOSALo}C2wBO0y&DnK!is!9#ucDb(e9bf#Wv&6OabB<#nmIrM_COW}2+KIJ zS&Ey4U=?9}B3+Ve?Nc5E2idYx6xb0k3hscoDFZw|z|H8M4`VbcQO1M7bEn#lbYHCK zpsP@>vd27~+lwygd`-QZu6S57EhcXuN zv0_}U!EOZEfYTj8XvKrWPMX_rko(GfvCgVB@R)uOt!ef;s8(dZ6LF<1UId5#&R)^J znBi0WrV+iWqT*xm5==}r8a|4@ZTQUt^=jTVt8+sXk@kju!}`ruzB$QlxU4{%7l@&7 zag###=Y?8U@|?r<(Bs?LaA&JJ-}}KsM799zH_+ymv_h+IQ_qKDabmEAlMO57-meVO zvj?#^+wRI@K~nsyuU(^(0^{c@nSbqouV7Ryq@lf?Bm1+L-eJVo9{0b@3@>YpZxN3X z$}5ya0OFhrDVqt`#g2D6ud$ny{ew7954(UV^uY*Gd4I9Ziih z&B+X}vY{e?zKZTDRI)N0T6t$n#GdEsVAE+>P~xG70aNY1P4Ug*GIwibH|REB8$B7M zA@gG+y@3p?Uj_E8Yi-+F!8?m1j~;`K=vW+I?^g^q4#S(8>IClX2!u6EyS5fYj8juD=QXn#jfj;K z$|BDyU8k)_BW0)@P&WUmn^|)G=$9EW^OFHIY?|Ok;3GAS16adX`c$2%l#@!%7qR0~ z&{_rR7nHrgh&N||+#|$4t7KU1S;uMoX|W#`vTrSC&v#$6vbnX(Ccc^TZ()r;t~~2K&utZ1uJ+(-nfxmMKhLp2IOYD2 z3YF5TiXWtp9v+1Y)*iM4u|cPa)-R@|YIz+-hY7=?EJ<( z%lmeiP?vHq6MkcTUu&aI>u-?H6|Z>WiM7I*@xnX>kL&{F*Osapt2;2@=8y#F@qY~d z3?Et$i!^KkIFXca5_#C&pfb>+KIFH4H9+kM#7_71S&_h%|4LDa84s^ zQ;ELB;h#Asgx`7&p{LUA<*t6l?2*k@I7k*5&%92aryT78cl?P$pBG@KotHRv1|bx zKrDc<3g%gINDKrrBh6Xyy=CvwyOfuiLhFA~ma}Fd=jSdlokzzAu$=M7_5auQEm;Z{)Kl zxLf?s;HhE57-+M|gwrFNA`gY6WrJX`3|NQwg{791lOC?`^1DCqnmudUT8QsdSjrLD zkkK!SR6`#_fo`vt3n$BsaB-%Rwm}O{2&i&lL?~1mE#wL06_)yezE|&wxHWvyY2X+< zlypRVL4wbDga&`6(RPG00;KoFo*d*+ycek&n6yLSY^LCa_wx?yn^zZ#cWylqVrkpD za8l52c0>0|9NcmR_$y9vrs7uHyWlHuleHLe!T$<=5C=U1fFX1`*UE;`^qB)RLiQ7Y zYa#+8pkqW$f~11?J>5%x7ao04Sm3#gU*l)mTEN{t;qxpZx!bCF zC3q`5zrGJ{-}I8&lu-EdI*)?>x0jO&<`OIvbd4DUW;fXr=&I?!6l^`?uPiW4oTtfq z;ICU7ZB*f!YlVMw35h#Du$n-vwpSUmr=9o7 z+S&~i-ubv-+0`%D%(&I+u%Tepg~5AVPH*2GOeyrkPTgm>WWWFg(i*=YOL7OT4IxCp zHR}h~J^CQltvGh(^hz=X^KeL zJ4(bXvLxmYP>1&(wRic`dEdIl(|N;BrOFpsPTgSLTFBklH~z&)cI^2|=q+1`Z5KIBb!3FpvZo_ra%(VMM=h_a069(Gk z7*%%K*LHjf0mLB0MYi2e`7CZLptG44c~oz_SEMfKN38s?oSduIBaZ=J$*ooRGNoLm zv+W!bQlaLHI?cUc#I${2wEP%HM`%Q1=$Js>OeB0dH~us2F_ictO1KMRr~`lx1Q7Yn zqqc~d9zP8r3&IHU?R(z(V~E=y%tv_@6sRQPPS5CYV5mz6`nPC4YP^kmE(*T6hs8vq z=X2^{pIU&ahg41&`>0H&i{|)ru|hIXagg|a%AQ|LiHNV_E0d0?AZ7^KiWSX3VdwYE zLUIEI84+T;E9JmsL5R-gQa~sWE6%j66F?hi-WsBf>|Y#Z%i`THPb8WoC8Uk}%>RZd zsD-HpUNh|shoNNZgIj@@@A0r7yPX!ZH{s#_TI(z5a0s5%cRJ%=+ryCU_wXa6B21hB zVk}Ljy(a*n{Fkf**x8h5ICaXrCyGwxFp`oR$}3f}_R7;o3TyC7YQA9oTxVOKpgmGO zj{O}wQP0wjT)MeTsQ8c5&FOxziq!=oJ;#jKoP>vXg;W|h=~kc(L@a*y07T4!gkIza zEdD2|fG;1%rND%^fGr33g~ZR$4NM2{2>^o&^mv0Rv`az2+~Yp|>D#HNE!#5AHJ0X< zVSn2p>Oajg&Mm=G)qBpBkh34LDux|TBjUxhTm2YA1uTHVh!mv+Aq5NY!etsQ7C}Vb zt`Cs5-4&6<(xzbp>)6K+6%4!$1AOiH?Fhb1XG3Zy@BMQ4NP680dk=Zu);-FY)hev` zIao&aGdRG>q5{RC`gqr~J zhj6dXUIZ6{+yl5U-E_ba$-tn=I0}RDVfF_4`nV%@eQw8ozq_V+@t4|OE>1i_yNG`w z^Scp#V|moLJdfpxj?)WGLj;KoAFqkJ^WBTz4HrIgg&u^ozD2$WjbP&dKP{coKuTdp zBy-4jeF#IJ7xvafqC1#rSU)pWxM?_3&lvcjX=9+sCl7pN5L_9gYCeE|~)w3+GuRp637q)2Hizz}P; zQBMix%H#nu>t}T($$%Bdb|JsxSWE`Q%%#vmE47t#DI@@WLn0gxBW{Jsdu*Wl9@yxF zhM1r;Rikk5w71!U+?GY4P;Yd1=0RYp;=gpdh0;;4Q`pQ}5?U~p+g339Fg@s3 za=|(?5CCdy>3KaM_k+T+MMZ(y_xm<^`uSutQ$ZuttCX9g2Swq%i1(ONSUAFq?VbKi zmL_%hDmyZtTVE2J!~d2IPrPD?_oDYpJ#l+z3DfZ6ahH{(RJs?uTu13P%3HE#VY{K zLV0TGWKNePoeC#fLiBQBQgg2}J?eVp#x)g%1h1*l4`l?a-kB z11;wyzDRm`&h zS03uW4CGRE3_G}M7RncvWyQ{_fuMbDr^wn8F?^7SBc-9BMb#hQe#O>DL1CoGwVLc5 zxW!^nM1^lMxlvGSiJpiiT$7!M`7)59=v^@@#WCagO-oVeRcc?j%sD3=L~I5b;we(P zsJR3JN+pO!;Lf3lHjTtn5F-Jlh&dfXL^;CXeRedl2OtG2<#7<26?rNb{Ms}=H|Fb4 zpVo+ewXi1dwUP7qx#>#c8%$r?xcjkxc4tG>c~gskk0tb+TFZYl7Oj_oanDS2QF3_T zqSU&pd;PZFeI6tW5}x^P{#`Ws8F|o?ujR-dW1hW z-gsF%k?}=8g;9HULM#DubzvrcMX7)G=&C0Qc@z*EsLUjjdj08@ahDn^N z41OADe2bM{uwIYCoPg<32d0;&3Ky$-hcP+z6REv>7A4}&guMMHsh~ofKYs+&T;F(P zAMR9=OZlAoJG+`s8MiZ9&v@=}{SLY+WUlxAu)lC-b{spUOp+=HqT8>|2D~}5&o!M{ z1kwXQ7Dj5&65A;Q!Wl{M;hC3GOS`=bruyS~T!gZS^tKO=E5d!IVL#$uQ9z2*16 zqXg=}9xv)ssp?A>WzyqkOxM!;!aaJHjx-dQHClOiYx|d4o9ca^rs+MsNY;Q<;lhjy zh7uAFr3*~J6tdl;p9EV2sVI}A2X~RqablM5Yah7&WYCZ`QBwc0!}CiCJl%WQLTus` ziG62vD;!Q4{e#k~#WgRQ>&CAXmQ*;}J%`hn3?165dB&15#zqs8XYzFdT^i=^J2Qe1 zzEQXz2@?pCc=juP0vc1V1XN9{p8wo_C?2|=r`~vX>V-VWESI9K)PvXb%uMeL^q(3IP4=cJGOf*Xm;K|JgdOD<6^hed#M7)H)1yOL{HHq)$>)Md*!WSnPZVLcf&YPWFq7x z0cbHmOz=B`OJ68b?jdp#B6WfG`j7%NUbkxYp#UhIpuBh~QqC40lH@&pfqdnf5wqmw z41)G*i(mI^<6xhUYkj{15-Nya_)_hcFOz-i7=mM3y&-!tR$iWzJR@p#_UI+s7q=!B<|n*13`#P>9gLS} zH4F?4u)>#!o3j5bw2Fmu@ln{ywQJW1CQ4&EU5bJ(6}jsJ)l21$O|4Q4qlePER<)DI&MALhBt{MHI z|77yT;{t=saiQcv?~SFr4L>({SmO{rctu9e%r{jGwaJgytQ43TekH~jL| zyz|>;Ke>1RauVjskut05&VpO#1!kVLeAPpIqN#>siayEmhAo+Aw~-VT(3r6B+%`FDZT7>O%i1r`XmH(F1e>R$)=RNky1GRF8xfN|8@1y(j zNDcPgwBZ3iUJJ+HrcC5dnUb0N{8HZPZu|WaF6CaAaj8|O`2~+|g;c+y#@lH#ZAz0% z6N2qaB1J%@&O@RFNt>U-wDpI_zO)F26Vb34I`O+%D)5)lbgR64x?ug{vA6QkOY>J| zZmcfk4y)L{pJJBbO4$e!+x02f^Y>CHOd=`UXk87LCpT*Hn2x+^YFKROms_T`m`F2B zF7ZKJJ1=b;+i}J?L*`Yykb_2%)_kT*S>^8sGt20$kJN3-FCkqDpzdV>9`zMkW=V7s z2(&Sy_x{u5yUH%{iCM$Tt7|WDmGVbteV*=R-~K9ked6}#O42l4@sU@$KCh#YcD}Io z-%zO1S>)&_rnk{>&&UI-;vDUs^|#nM>8Opde3Se}lkf6V`)%X* zhM&bu4-lEP$E!d}17MCc5++_%I*p`z;H@!$k`Ee#p6OD_k$G#~e*lilyKAq)5zTSx z@>PbbnfuaA{}bUcm_NCb@R+=Am?8dXw^D3WklSxIh3YJS6PqYuabfSR&3UijYHCtU zhYDrH2T%Qj(WPl;%c^*W)%ugR0(&F1wT_8~fo#3<%zmU9&$F=?UiIH8Mi$gC}yjdQl9NL|t^xN8fi+-$A>z8V~l)TdWTrB5?brsW-`rg@=Zl+4= z8Cy+#Gw43it}!Jh)BNBfTY>$}sM5b4$>kwGRyXtSC?KKdp)b~56{(-1X$+MWK{heM z-e@yF)4jr3A zofHovm1Nz%KR&eO+B-P9tq+d|O-E#(CORU_=qDrlS$6gVWP@ny1|md5Hg@&B>^tt) z2T~NiFv(`UVCd6--mlv3ub;`MIwMo8=XkaP?Q>1JR_{a!!7qds$Cqj{4Lkjerh9)Y zcBtCc`aSqg%P2I&cctM-f0vGmLWm+MMOif{a$3v`}=R=q%3O&j){`0x7% z&LPFBLFknr_LTZJAq0WIMd#BJaVG8N-2>O7Ik!i1%w1VIfR1K!XnVXf<%QZS_XdH5 z*%B)uq5XZ98lMaB=-wK6&G@@rNu0ke4mB>W{$!U-ITx3$nE5ekOJ7)Tq#o08pF5j7 zyUT4I#y^c^w3aLm#lQbpUOX>Wqt!I}&dMaraE5AS&>3p0i~In6axFtzU)}whf|m^) zRWqt5?`xlzxO!{bx6BYEn`D4_f+Xy`9H|Fa5bkR7yf3OU`V1 zj;Gs(M0{-=h24lhn00vL)@u62v7$FZW9~j)+K%-=*}6|EU*IqGelF0X*%V@xW?6l* zC9XwqF*diK)SdA3t+mr-^O^Cz&hT^98j6$va-fk3QYgpoHEaWvsv;4}L=;vl*>)3fYZA`;fG zr?{H+C~kW5)VuKwmGuuY9mW-2!i9FRd#ng2lr^WSSFPF^77G;K`x#g!C135*n#^R5 zQ|K_4b3Lt?F1qmb*;7(Cvyrg1;B8&#Vjq%1YNnpYh->X}iqyz+uB)HgU02nvx~?i5 z{Xufl@BML=$Ks^!xd-uI0#CLM_B6HTDF)q{{d;L7_8UCGmrXjG(;V&-Ndm_jPF<7o zsci9FU7A@df3vCnIeODb%J7O|K~2#=v7&M@-P%PgS%Tgg-*1r6F1NRT{X=cW0|9p` z`7e#-tKqA&%dR@<1lyzwn3-p1@U~n*MWJFw@qL;S8j0!Asg2EF))ajVLhekvjru)Z zYUe0$Ivv%w+bFSbx2aLE73{BT?b4=kD@irNE7Mw)@*{`85QLt2wjxjU-1e%e8)4i@*K(!t#rx zwcdh3Z>-zM%crC-x_HuLB)*pRv!>u<&^x7v-h>vVbDTcvtdasPna7bIKJN+3E>cHr z-avNbi`b3YR!yHYi~B0qrORZ>PUVZ1jccPNOWQ67&n~nMDwY+Dv!k!FE&kcwyw^x6 z;r61*x7?#qlLp~`tCapoU;c7JTYz_c$g;y?)7*>9pkgX#_0cvy@F?h#+cwLVRbT$| zjZtc)m}!lfspY-v%ZN19xbN>YcE`qjPgkO@r3S9w?tfh2$N$8>tzwj&SzE62aRU?aOOcpD*N$PI3nm6sm>VU?`g**Z6H&`9}o zYtc>h;i|c>&0-P{0yqC!B-LKdIx*1|9qV^5*+&W6(X5<*p5y(kj<>IkpL~1$`sRR& zPDpOQuHw=u)qnUWYH30_ZpxvgG(58(n%2LqCh6`G&DBXth(~-e&S5HI_?ys9{<}R| zu56N}W0oRC!}lEx!{?MrEYfm37GHK48idZxm`JrQcVv3Tt6X!(&ezn>T5a5JSCULZ zS2Xc-Al0L$#O9JLnKGw$v-6@NR3XXo`b~1)duq}#{sB+xy1RsaQP)Czp82~R538b^ZR#dF%~Z&YvG`#SucM zic01w^(C)fz8bf(9ebbOKUXDn?wP)H$1#-uQ2ZUQ2Q~ttDz1@nhlj3|va=xX#lWrkz37$rWWKR|OFKUiAC=6a8$0kW2TQ zWU>#(oKKRnf+aE-#3+RkNP^3zm%Lohhxd!03JJgC;v#xZk|gbTd;2O5(w5MWrEOA^ z*Ka~Yu=nMb?DV>gix@uBk5T%{%W*bI%IP?5wO+$5P(~Hku%5XjR zK(KGd6Lpa0@js#*8I;)8-;JuN4%uiuH8Va>SYAMB79Ry)|M<_x2#-#nW+KOrcWsY5 zy~1yHAn}>9ij3jHmFh`)qURFH#zNcPJS2|tkSe3tih|}B(@R_O@Wa;e&-8EB>ND|+ zn|^lQVO#n>JR1DneysZZQs4Ld?+hega{+VCmQZTjWAfx(@u0`*UbthFUM{Xa^^guSL(!x%nLNO&{Ec8AHz@<}TdVl; zrf%?=U(4*vY-DSOz$5TF#CC6ht7Fl^-)oj9i`qa`ywu}t-x-H*vmYlyhD3krAbyHl z-Vl8Mz7`RweysBDbhoCMwt5`zbCDPpDbpm8j>qYT*b#;0I`_-Y@Rh&>h2gP`9~}_$ zR86A&BQkp=(NFIDe&PkYsfY?jn};7h6=RpgO=+Iw5##7*`iE0?Z~sx*^nnXo2gJ7PSrwk-_TUtr1nlz2u`;)m^aG~`YdA`*j=->#Y@Y5d>)E1*yD^W%n?l=6SByMC?|E0u@XI!!^t0hV4&HH zOMWRZ=h@Z>?vUwMSwi+rXx``f^vmf8y*(3k&tvw@lE=LFRUtnDUr0aR$ir=2P8@!z za~AauZ={e9*^oziS+t*Rt9~O-B^9;}=1QGoO)w69rq7X}0e_d*@Ua|sH}I9FRxS?h zCD+>@fxx#lPUaui<#s)dH^L;6lNz@u&d4Q8>qvF4g*bZ(QLse^ywlseFGSd%qGuYY za#wxM6yd*CWUyCfti$ zFr=@+r+@(p0uoe#IrsgC9JY%g+A2Q^$eUx}^ zFdB!3jnICKXXP44KGVk;!*tFS*q!g24$LpaYS}$It9+8Q+Ki3*gg3&bDoZqc#X!Zn zc#e7Pb>Y;UE21z@^M`P^PEawNn{Y&AeSjHE?_7ZmxCEu-+newut`3=&;`ogfx)SZQERw)%&7gO7n`fmp|Y z3H@pem#8a`*Ndksh?j!C_QIyfScBz4)cGxs}(He`G8x&71elC|zx2z#)5?KE(RRVDb0`cjSa-Pz|2_YKHhXOm)*!P_>^|Gt)Z z4A;w-zLTEz$=Z$_aB`I+l8A3eRn3*GjdIHQFgJmc3orTba*ro-1!4V#c9m$_IOc!O8^SFbZ8U$%p>y%>q3!eZ!WszPdN7zOeB zM*;PN1Lsz5mAOsC4|Qb^$q9j)Vx!2Zm*8^fi!Z*8emR1DM%TJ*r(cIP+|NBZ42dBd z^Gb-zxRzPmJHU*E4jM?)R(<+?h2bt9n?!H3_MS>A;lS$W{&THY=?|vjcDK7!a(?F`i|w1cW*7VzQrQD+0wH?vRvdvNpKGmTUhvP0N6hreV5aLims#`z`%#(`pQCaKU9-$ghpV!N zA?u7~G6DQmngG~u0y^<5>Qz`?Tcnm<=WFrY6OYMl6=n?pNJZbDV1s zB68dl_cq2G5pD-IK&9=HL-jJb(#X#HB)rkKJD%Rxpqm^9H#6y1d+PSGk=u;DlYiRK z@I!^pg}A-Th@iKSR5FX6B7ixViEm%C+jUct_soxia7a^p_m6_tQS~Y(3De;mD`a=# z1hsX2_0+c1o847&?H|+gY`>N$Hfk>h z+C(2PYg1r<5(-eX_w4oax44LmO$l|z$egp!2irbr@%p{t2jj{WOwEq7F5sVID{G3s z)D0%zWq)x0+>N)%<7N*$&2Wgfo;4@hBAS{x7vVx)>Mu}-zOjANM|PeT9NSE;*QRAQ zRGg^ShPvFKUq)_w7y3C=;ll~aW61s&0p0qc;B&If9{f&dN5ih4FLRU_^{BkT0N$hW zTd>IHPA6n5RT!XsA3O91S!Z+S%30I4YqoS-q~4nW7`m0b9%AIH?OFOpb*N=-87 z+|s3KCgvgD$^;Cs9mhhXpW@bbipn!%k?krY$(r$ZSa#|^Iw8#n(INfs7p4TA&Y995 zhw0~#%6!3$5;Oao-qIxBR=km|J<(6=>wAXCsid<~UH7Y`_d4cK!>|T;Jbka z6yq#Z7{HfrMLL=I(}%z__{3gN)znB@lD;i2-}C&kycX7UGcgQhJQIY=-;c$xumw!( z{F&%|`4?vL?TC6muj(UV@`al_iBlIjP7hp3Z$~>ABPgBC_fg|dk7kewmCY30bF5hK zj9ESxznPmZUMSlMzTty`aZXi>er-eq_QTCh4WCE`EjApXk9!lo?1$1np%UVJ%*b|B zFC_UDmYft*E=o$opH6^Uhclp4$j%3F)Eqf^lv%LsL2>ge-UVsX=*4g9>5FS=?s6oa zD%5!;MISA^J&S^~HHKeu7sHh^B%kwOp=Rt>pX*CPKU5s^GX1!IfjB}g@W=4JLJ#?= zdo9&9)CcWLjpr4Y^xY#BD_vXB<>k{Q-aTBh*duJ0NWQ!=e5qGw1I%$=^F6e#RC1&N zGF%Zq5q$@YMzt3u?mKSd{#Xt12Qm7=cK7#hx2J=Cs;b$#!`lf&M zs?@naupjtKh(iA2JHd9-u@B--T}jXu@{0Yb&~;Pu`-S-{<}dC3Pq2t}AGC(SF)Xx) z8#E~H^oDH%>D|_4*;qOi(g$xYxJ3;EJ=grnqA6-_0-m@JIcf5qJqmDIj4FVUju?|c zGc6as9=6$)DusHy|)SoWC5x0*@#%MUsDx&t!~}V=G$+ zbEIrz(sT0i`)ts0?7_5|)wC|o9 z9WFy(iR^I;WzB5?tgs`(H+^oiGQRxKX~~?ub!g}%L}-zMbbihDZ=gXr$+J3g!t)E= z6L04f5_l!waSdbs#ahxPEtW%hv|2k;bF>pG(_gcCl9na{uWFumiWM(ruqa*p_7sUD zJr*TN$0|naoM9vEse_6+P3Pd-2zr5s^(iseg}k1sGDL*UKZ~a+3EZ?%%nPhJD9sjV z_5$)Qntb^q)#mNo7zBER#M6}8WTZxz4s;qnwu}UKWX1_tOUStOXf0@94lZ~BFWqZWhmO@)qk-ZEc9s-yHksKpp&Rkwu3bRd__DtL2IM?uFC5{ zcRbF^k>4X-zLhUDsnz3Z-?rz7E5mEg@i7e3bm*Sf&WPpjofA!Nrqhy ze5E_Frr~?)#t|5JC1IUo>a~gi<65@~pL~Q8oVndo$qGlO0R&otoAGIf(J=WYMO`MD zKNkBx^09uiSICc2ie25|+2T)tn!SY!ZW#hzCkfL`_4DqTs9)VDC@$I240tc!i93~D z683lMpZCup2YMt$@J9KZq{Bpci?jhY=oagyx2E0amyb^KAg~5f5eyv}GOp*7wR}rRDC7q!c)=RXjgb2$_lJGJalUS^T_C7u8 zqtm|UkMorS7Oz#%&Bzg#ko^+Iqe$I&;yidST%9kQdC01Cl3k_F`tb<*W;B_9r*S6Z zPI~>OfA$gkC)qkNGCF)xIK!Foh2LT#aM47vGp}JL51k9`U(=8eV5Y`=CvsG9C_k30 zjcW|iyC*k#4bc)VHcT8>An}NdI#^GBW5XyCA2%Q=6yFC#7Sn5tPleM)D?(cDrof=5 zJ`|uX4ty|1UYiyE$QSUl;bdDFS>UIFr4v@c(UcSw)7>n9lwwV7FQSU0iD$HPJUa&X z962!tbYb*g*%AOi^e>-&;n7ox*;Cz>;!p&+ej?=7cVR6NUXGrK_U{$H1^e!NP&X@H zwC6eXdjR`yr4*HZD+?jd2ix80Kv4)uv%LLtXZldSqz>3~sh`1hs^+6Vm}XQfZxMW37)|J+ z06=5CA%V{$z4)`@bp=J{9aSMCVb+dxDrHD?>pb?>#($#J>QGt=9~PAgTiO}QTt&45(9HhC0{>tWh+UB&40C*n87O#1eOs9Etm2fPv9hQVAtH@Pvt{jd-YrYL`_1bUJ<5&27MH^I9?GF zBDr>P#zgeLV`2t=`GbR6PkKc;{80rXoylqBLD-!q10DYsba}&@r+(qv9&RvxzBGIp zyR>h+3I0KIY2U4CeWroiBXyoTk(PwmApf-Ywm=6DT_QL+NYT+YA23~(ttYVcFm=iG zXVBwAqQKZttD8XcXEPDR1p2Jt%8KLJ1*m!EsdA-KW_WG|tDyUSjTsf{B-Bo*;n09% zOi<`m+1g6aiSNEk8`l${JT!~=dvP20bygN^IS69BI0*mC*@oGujzJToEa%)KlT#&8 zNQpgcMEL-!`m1DeQWF^K0;v@kXkt^_Q|HclN(u5u*w)kFIKZJ(I+i>~OBPQ1Q-b|; zOk;UXk>MN&RYMld-eAOgQ= zBI-z{nCD;6B2hS#$(%LY)_~5PUq?r(V6!`%zJy<+Jt+y9RPQys`LNl@K@RI&e&=?+ zL0k2!8L{$|54s4|x3EuMj_=wkVp+@J*LA`dFdrs$Ims-;$*`82i&$MwlIqk^oWI@M z_%KPW_b7*qXONFuqxKlC1ZW9YcGkCvWMMdOVb!IOn9>4Eu(JghV}oXyoy``L54)2q z#%I*M)*!b20pE{~iN>(JFz6G5+h|a}bQQA_rjOJ1C?CVO0lTQ;hlYH#BKa(*LZTJL zOla<5u+HeaB;eP6S9P{t$yc3@(AN1a@B1%qI6zJLotp^#EOZ^_N*kUlP4;*^E?{yt z2mqLS%;J)eYoO6%GJk~EhDstdQ34S6M##vij_Vm%a^|7qPCrcO7zy+$B zc~%+6Eb{;r+=t5gB_Yxi*jC|2C2&5?t^!P_<;5%y6B=0=^$*81AILdqj3#^hCaP*| zK4h);;He24yU`ADA~R!vI-te{SR_E{vhghE?8FUJGawBOw5u%e+5F>w!Lky*@M|Dp zhv)v!T~V7Vu%btm+a;Cpx1YB@%@Ep7<7csPX+0AA*&Z<`=m-zC4c7A*0Q|yGwzgKX zdcrQ59NlAaO_EME*;>^~Ugq<4pWBe}jSpCPgc3T)&vDd0 zJo5sAR}3%#R|i_F9cQynKtKFiTqpzL9^Iq{Q>_Wymv34H`*il!yA1sH`d|3UPLe)Q z4z>FHqu`R}S|Do2OsTQK_%K0ls63&H`n%*Y>_!q8a?x~zQYGRLJ&jM~9C>0U8**4} z>XXm1io;W&eQXd%Y8awb?5)K;gJ^}bwn+qgikLqv7ta>Lig-Da-J=ru2E23e#fClU z1q-6Zu02n?|VA(BZq z@woEJPhlUvev27Xu-)ro_K4x56vC);fj6f1y{DUZ5xJHGEC0?v)Ee@*e?rAm819Uw zAXW1f>Tl)ZY0Tp+m?=<09qyx+q=I~!wRsb zfUh(fQR4*q=pNwt4BovhYB*^1r`tKIo^Gfkp3ECP2b25_q1^3_>&?g)kOW&?-f5%K zUuIt$bNVjRr!H8h@!bp13$R4KYClm)4e7~)eG zPV_93sVLw65rRKq&%LdaiBX(vQqg0 zW%dBi|JONas1n8~(D&&VX1Igd;wfFAp%qwRcMQvTiFXoNxU2v@!7Ng@Hn@tXm)J$% ze&vuj`d&5%u)&qN+(JE63HWaROXZIVD6y`@;F*V0?tHq zUv;8%!+4aqrowlQDo-67^cs#HT(}N1zIF@u?R(|ouQ3zNfhdQ1cxm}~(fwbl+ zN5Xvhh}`)`$cmcrq0F08cj_N6_nIB9S#{v9^g!<;#YCka`A>>!nh22|@81bAF1rPd z01Vp!OnuBY!~2G2>EerYJD!(pwPRBeWr&mwibzbQIL*9mN86rACeFrNQ)y3H@|16- zR54vBPsJAs`;}M5(C^fv|yJR<7HtoA|82i!&! zgq^B+WDE97m$HwQoM4-G%_k#4K~eXv`#bn9RiWDjJth|=jOh?{K9W3e6@i2^m0a8X z;MXfZu6 zYICB|F~}I-##?cblfSs_BX<_@t20lmZ$cEc+Eaj8+nh#q=Lt?TImH%LQL1nO5t>NV z+z;+rlQk*rf*cLs_HoPh8A=3x*6Z@_;ttae^&Qkf`bA2|<&$rcJEFMLAv? zO-ang_5}@Ujbv05drRM#{Cu!9nq};0_)X-rkRub>48sZ&`x9nFzECR;$+BnvKz-kh3eB3ZJ0?#NBk)@nqgo?E>%z6JqX zgQ>k|_uztO3Qv-xP5A(S_BvS=CJyny%9-?qvH)@BY^|sx0OH}hZRY=S9n95$)o}We zB7@>}YAHk@^(9qM63*#n!&?r&P7-1E`2104G-0g8!{5c0aC)&DrH+(*5eweq`SXP7 zgW9)e@xMYX?GyIj^;`JWe(-Nlw(5MqVnMeu=Z0ih2Mi?r|Ly{?Kj2XwB~UNG0S~G@ zI;*FsuzDrDf>RUlOdLAt0Sn#GZb^)s!IAA=SEUH2L5wwplYbecW9Fo*Am`upJQ*bJ%Ac;qfSx ztibxsu+U&uVB)mS2gUm5M`LJu0 zJVxd*LsSJeGmroCvYVC8m*(Obl6tk>`E?~>cHc>q$UlnVEV1p7U z$TzG4w*7auV)K~-DQ4hsFt;zEy%Fu*gCP;8RuUsH(0Vm85?}BK=_!HbnGTc8wa@9c zvD#agZ;`s!2#qQum=77_6W#izgV+hkrjg=Y_XFhBy?nb^L3e?QfQg+Gk59DAa9wMJ z4D$wABxF0p_o_J8s*~nE527}(5Ch(mp&%rZ(jwfkXgFyR+%?<$Nfa*X0#j_=aP5C8c>7MA;cg7@eD zqSvhNFLvsI`I*FAclx2`yqj&c1SZD^*qb`{P{BLDauc&1)r>FWqr8oK(p4onjW2aR zXAN560}Fw_@SIz;2+c4f4ouKLygPlJr9#fUUf7}ik^((KmNnp|fB@DdecmM23i?(7 zA4L>zJu+GZ)pH63f0*LvX9!gg9&CH6>v>>}dwMhXr;fa(2zvX9T`{QvzS`s3YseGB za)XCXBX^!xb^Au01bpsGlj@;~1Y{liSo5XM1C%G~6LFpAGFk=CN0+ipon(VGN015^ zIEp3P^HlDLZ->sZiNiTd#@TYa@K2jmMh@iukpTu)-aivjCgG@CsLv`R@0~j!sxGyz z89m+P)CDn)tJkKUg1l)N@%B^)|CDQtj zcen|P8ElysT*B$y2#ocA84Ps0o<12a;?U=c2QL3L6<&2-*7HriDVf(*m0>S0(Dwuc zuivw`%FUJ&!q1%tev@$8THX0XZR=mhDH35ZN1b{&LAbMyQNXR}5a1Q{2d#U1D zLj`pX4d?IXVg}zNbn_F*&X1XGl$WmH5eoSwY2*ub+6B1okDQAr7PE0zwH~X07`|_; z9wv4QtmL!T3gkXs2qH=c#`Cp?#)6!)9g?i-wBdA1?Ryd(pMT4nlwFi0l`ihVK)(~s z0pRi%p8A?#M=6|%q~Nn{k92d%7++&NZhUMe=px|c@92^w)VbNb;=w`;J2O4mZVinP z@cnt<$W{T6qaUe8=176@s|2w#Kij=>Ja3^)Fmi8SrT&8Ro$=lK;W`1Eco*OTx&_yF&sNXmv9_F0%!_7}+GNUyH<@8mc=YGx34>*AE-d3?y~93yB@ZAy|*KM|Cc z=T;3z@S=?Kv80+Hu(VuC-hfWb*Jxp2>j(O6*Lor^ZGxF9H^Z~7;C10rXXA5Yr@m(l1N z+iENMt~}@+X|cKYY@6*6YC29rduBmjNNY?7!}%cw$1qx^pdj3I*Tim8xb+Wv|KnC4 z?qWWlmMRyvpcoSF`4NOwT%$dR+Sp#NK({|aft!2M#Cx&`k|0-V?fUxgz$Hb9Vh3SV-ZfKH&w~gg%sYL_ zsfZ1TUft=ropY!#!D!dR4?Mw7#w!kySAS{QheY%;abDmujcqJ$jfM$n=+g z4(NiT5Dah^{nk)alBaFLLmcJx9WyI&rQ;t!>ZyZ2S?bmG_Z=FpQ{WiM!~`zsE_ z|6sh?!*M3IfBmw+N9_1h*)xj!2|YCSln>AG4iyH_9yS)ejeq2dE|^q{MuD@g=if(= zFDpVWSH3^$b*n|WWOGxQUR@IqGDrIKE4N$$Agy$g;MDT#dope2sg~7xSaXqx4&C+q zFkCPL+E`{U{fUbRCmr4gLRv{YaD^3I6&D@ty&UPz_bd4TY{Y)!Sw3Z6`RfGUIDnC`9*AvEx7t;*0JLH1l`xW+*M3mo)e{BJqn{x5<}!M(%73+sO@mQ9WwXm&m2H+hlWAQTmWha zaK8h#&EJm9kMVc(xEiv%TTQio{%yp^^$NHfLn=HtE4geTBfMcdk&C9lXQJQ3dU>E@ z)?+lxk|_3e48#w&yC_;*!C#+05rs2?If!vy5mp(tr#>rOC@tQjusf41`~24)M)d%z|1AbTF{UwkMX3}-jV7V@yho9q zk~?+K>0ceDQluY`zmi+E_@;&BeYl-yaihRoH&K22P=v-g!&qeAnS!bk`Yg$DJ%W7U z4dA{p2)ey)R+Sa2ZB#p#3Do0LqY#D;W1+d0n<@};=>I-6P|T>4#Ba0?8buFcFT*OK zBeBGD`F59ep?{b4@vj)w+2@>o`;RosjZU9I8v0h}pxyy_MVn*Qi_Q#Qj|DykC zF{{+1eFpH*q8PHXvOV!-!&QxQGY>8J8BOg1mi@X(S5-@nuBg3E3hUB+P~}p)ZGU!m zf{p|82$VgKo+2qKMnYp5Sz%2O&7y-pdQ`x>1o3%O3cd;CvU?DLMTH(r+YGi(c5SFn zMoTaDgGtANrPCGPXga~WEFW>L`yFLQ5^!1#7qY3oqiac7I8KeOq>+I>y7alGH zVrc4!BB_+6je&WBg;bi)L^5%E3>U<~`#Kq|yk_ z1I!N>7~=;HCw*#)`LWKck@uH31g6qO$&0hh5|Q&93Vqo|y2#_$W)G%ThFwGIe=>*C zJOv{;N`XP8w;icc*MHgSge$HqX>Bu1h&oSOXNGw5_JCW}WLnVLetL&eS#Qc|JfQX> zub1nnhuMD#VIPh)haVoM&yO$vLrLU^`YSuc6|Hzi7m159tOUKEUs5TlSNE%mo1d@* z-aW>H9(e_Y;n`HR=~q3ieuq&~$`iqrldvDN_H% z(Gjk97Iamz=iY(oWoF((w%u>ryB$}zh+i-31xksPhC##lBzjOBgz0S~m*{((E{hyJ z*EW+jm-0$@C+u>%bX7C=)y3fGGz$q07pd#*_0>@VwLIX+&?lG@)jc}RQQ#oh_y5dp zgKyxCSe#g)xuBhKHPwShpu1UU1d~dk?}y&?1XP$FaFldL^DBX>gy9+#zk+t9az-0N zt33tYK>JY&KZSe^4g0cQzmcKTcLeTde5@a&Wf)nYGOR`#8u|}mL6mx&)yr|8ULe7q z*v~+ceya1I1(!=Qj0JyJ@ODjplx)}LOJnfZJzm`q-r@Texp=}go%o=bdhzem5*^7x z?tLZt4coTvZ5uMZ)AdY#V`p(-&g>#P-){Y7o(Mdx|2}B`;Cr67!{h^x!@y^_TY>#c z>-3}k=_nm4k^~m2jLAp55jPP_GEEFz@6KPM0cheG4a2X zy*elM3feH8qf9 zckAn4iPLT!XAS_uLC|;rg&El*b8Q{(N2h$~_SSs-qG?}^3PxfhX1}_(%TDC+5S&K#2{n_Cod;2*3oERV^AY)SDg!9i zFcyKt=RZ1u&*yQ=Q9F65#F=v$r#u1+1>VB-0&s!{NgVIwQZo=Me7D?L@KK6}qZf(` zJwC4JZJ)oZLEee{X1|i({Y34%uNTFg8b}`BD>!r@M-W(j02x??}NVO%%|OYZA!wY~KKNPB4$4`w)T0ux%S}-j<5# z%;lAIVP1)U5(9~b#?yv8W67|`2fyD0#oD;}79lQU7sm?nr}fL)ChTJP!dqIpLKeXo zk5C}e|LzRFe1!(RbjK#{e^^VPcG159-%C)Qt?Qa@9i&YMwJo0;zO2P$1`WBJg74aX zwi0FVuSLlUt2%)L53&&fYEtJj@{ohoQ~4(X6ok{Xn^dmf5`pUq0QmSjR}lPd+QhTC z^YUmp@RoGmdcKue%7w5;Ebt+5t(+hC`84>4boqph@VRx!) zu+YOtLwnD<;oc{=BTA3L^7BG}8>m09pOx_9qf1SevBoBW&+uk74CojfW<~@`@f|7L zHI}?VqY_Y;5W^|{xR>6uV*d06QsgCVIOIsr_0fmGCZ$K3a-;iV?q)6>)lyMXk

o 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 literal 0 HcmV?d00001 diff --git a/docs/images/flyte_lockup_gradient_on_light.png b/docs/images/flyte_lockup_gradient_on_light.png new file mode 100644 index 0000000000000000000000000000000000000000..1f986f45adae87bbf319c33f6cca89bba7a6eb7b GIT binary patch literal 17200 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ⅇPSM8nW8>9sLH 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 + The highly scalable and flexible workflow orchestrator that unifies data, ML and analytics. +

+ +.. image:: https://img.shields.io/badge/Graduate%20Project-Linux%20Foundation-purple?style=for-the-badge + :target: https://lfaidata.foundation/projects/flyte/ + :alt: Linux Foundation + +.. image:: https://img.shields.io/github/stars/flyteorg/flyte?label=github&logo=github&style=for-the-badge + :target: https://github.com/flyteorg/flyte + :alt: GitHub Repo stars + +.. image:: https://img.shields.io/github/release/flyteorg/flyte.svg?style=for-the-badge&color=blue + :target: https://github.com/flyteorg/flyte/releases/latest + :alt: Flyte Release + +.. image:: https://img.shields.io/github/actions/workflow/status/flyteorg/flyte/tests.yml?label=tests&style=for-the-badge + :target: https://github.com/flyteorg/flyte/actions/workflows/tests.yml + :alt: GitHub Test Status + +.. image:: https://img.shields.io/github/actions/workflow/status/flyteorg/flyte/sandbox.yml?label=Sandbox%20docker%20image&style=for-the-badge + :target: https://github.com/flyteorg/flyte/actions/workflows/sandbox.yml + :alt: GitHub Sandbox Status + +.. image:: https://img.shields.io/github/milestones/closed/flyteorg/flyte?style=for-the-badge + :target: https://github.com/flyteorg/flyte/milestones?state=closed + :alt: Completed Milestones + +.. image:: https://img.shields.io/pypi/dm/flytekit?color=blue&label=flytekit%20downloads&style=for-the-badge&logo=pypi&logoColor=white + :target: https://github.com/flyteorg/flytekit + :alt: Flytekit Downloads + +.. image:: https://img.shields.io/badge/Slack-Chat-pink?style=for-the-badge&logo=slack + :target: https://slack.flyte.org + :alt: Flyte Slack + +.. image:: https://img.shields.io/badge/LICENSE-Apache2.0-ff69b4.svg?style=for-the-badge + :target: http://www.apache.org/licenses/LICENSE-2.0.html + :alt: License + +.. |br| raw:: html + +
+
+ +``` + +[Flyte](https://github.com/flyteorg/flyte) is an open-source, Kubernetes-native +workflow orchestrator implemented in [Go](https://go.dev/). It enables highly +concurrent, scalable and reproducible workflows for data processing, machine +learning and analytics. + +Created at [Lyft](https://www.lyft.com/) in collaboration with Spotify, +Freenome, and many others, Flyte provides first-class support for +{doc}`Python `, +[Java, and Scala](https://github.com/flyteorg/flytekit-java). Data Scientists +and ML Engineers in the industry use Flyte to create: + +- Data pipelines for processing petabyte-scale data. +- Analytics workflows for business and finance use cases. +- Machine learning pipelines for logistics, image processing, and cancer diagnostics. + +## Learn Flyte + +The following guides will take you through Flyte, whether you want to write +workflows, deploy the Flyte platform to your K8s cluster, or extend and +contribute its architecture and design. You can also access the +{ref}`docs pages by tag `. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`🔤 Intro to Flyte ` + - Get your first workflow running, learn about the Flyte development lifecycle + and core use cases. +* - {doc}`📖 User Guide ` + - A comprehensive view of Flyte's functionality for data and ML practitioners. +* - {doc}`📚 Tutorials ` + - End-to-end examples of Flyte for data/feature engineering, machine learning, + bioinformatics, and more. +* - {doc}`🔌 Integrations ` + - Leverage a rich ecosystem of third-party tools and libraries to make your + Flyte workflows even more effective. +* - {ref}`🚀 Deployment Guide ` + - Guides for platform engineers to deploy and maintain a Flyte cluster on your + own infrastructure. +* - {ref}`🧠 Concepts ` + - Dive deep into all of Flyte's concepts, from tasks and workflows to the underlying Flyte scheduler. +``` + +## API Reference + +Below are the API reference to the different components of Flyte: + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`Flytekit ` + - Flyte's official Python SDK. +* - {doc}`FlyteCTL ` + - Flyte's command-line interface for interacting with a Flyte cluster. +* - {doc}`FlyteIDL ` + - Flyte's core specification language. +``` + +## Get Help + +Have questions or need support? The best way to reach us is through Slack: + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {ref}`🗓️ Resources ` + - Find resources for office hours, newsletter, and slack. +* - [🤔 Ask the Community](https://flyte-org.slack.com/archives/CP2HDHKE1) + - Ask anything related to Flyte and get a response within a few hours. +* - [👋 Introduce yourself](https://flyte-org.slack.com/archives/C01RXBFV1M5) + - Tell us about yourself. We'd love to know about you and what brings you to Flyte. +* - [💭 Share ideas](https://flyte-org.slack.com/archives/CPQ3ZFQ84>) + - Share any suggestions or feedback you have on how to make Flyte better. +* - [🛠 Get help with deploment](https://flyte-org.slack.com/archives/C01P3B761A6>) + - If you need any help with Flyte deployment, hit us up. +``` + +```{toctree} +:maxdepth: 1 +:hidden: + +Introduction +Flyte Fundamentals +Core Use Cases +``` + +```{toctree} +:maxdepth: 1 +:caption: Examples +:name: examples-guides +:hidden: + +User Guide +Tutorials +Integrations +``` + +```{toctree} +:caption: Cluster Deployment +:maxdepth: -1 +:name: deploymenttoc +:hidden: + +Getting Started +deployment/deployment/index +deployment/plugins/index +deployment/agents/index +deployment/configuration/index +deployment/configuration/generated/index +deployment/security/index +reference/swagger +``` + +```{toctree} +:maxdepth: 1 +:caption: API Reference +:name: apitoc +:hidden: + +flytekit +flytectl +flyteidl +``` + +```{toctree} +:maxdepth: 1 +:caption: Ecosystem +:name: ecosystem +:hidden: + +flytekit-java +unionml +pterodactyl +latch sdk +``` + +```{toctree} +:caption: Community +:maxdepth: -1 +:name: roadmaptoc +:hidden: + +Community Resources +community/contribute +Contributing Examples +community/roadmap +Frequently Asked Questions +community/troubleshoot +``` + +```{toctree} +:caption: Glossary +:maxdepth: -1 +:name: divedeeptoc +:hidden: + +Main Concepts +concepts/control_plane +concepts/architecture +``` diff --git a/docs/integrations.md b/docs/integrations.md new file mode 100644 index 0000000000..34ebfd073d --- /dev/null +++ b/docs/integrations.md @@ -0,0 +1,215 @@ +(integrations)= + +# Integrations + +Flyte is designed to be highly extensible and can be customized in multiple ways. + +```{note} +Want to contribute an example? Check out the {doc}`Example Contribution Guide `. +``` + +## Flytekit Plugins + +Flytekit plugins are simple plugins that can be implemented purely in python, unit tested locally and allow extending +Flytekit functionality. These plugins can be anything and for comparison can be thought of like +[Airflow Operators](https://airflow.apache.org/docs/apache-airflow/stable/howto/operator/index.html). + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`SQL ` + - Execute SQL queries as tasks. +* - {doc}`Great Expectations ` + - Validate data with `great_expectations`. +* - {doc}`Papermill ` + - Execute Jupyter Notebooks with `papermill`. +* - {doc}`Pandera ` + - Validate pandas dataframes with `pandera`. +* - {doc}`Modin ` + - Scale pandas workflows with `modin`. +* - {doc}`Dolt ` + - Version your SQL database with `dolt`. +* - {doc}`DBT ` + - Run and test your `dbt` pipelines in Flyte. +* - {doc}`WhyLogs ` + - `whylogs`: the open standard for data logging. +* - {doc}`MLFlow ` + - `mlflow`: the open standard for model tracking. +* - {doc}`ONNX ` + - Convert ML models to ONNX models seamlessly. +* - {doc}`DuckDB ` + - Run analytical queries using DuckDB. +``` + +:::{dropdown} {fa}`info-circle` Using flytekit plugins +:animate: fade-in-slide-down + +Data is automatically marshalled and unmarshalled in and out of the plugin. Users should mostly implement the +{py:class}`~flytekit.core.base_task.PythonTask` API defined in Flytekit. + +Flytekit Plugins are lazily loaded and can be released independently like libraries. We follow a convention to name the +plugin like `flytekitplugins-*`, where * indicates the package to be integrated into Flytekit. For example +`flytekitplugins-papermill` enables users to author Flytekit tasks using [Papermill](https://papermill.readthedocs.io/en/latest/). + +You can find the plugins maintained by the core Flyte team [here](https://github.com/flyteorg/flytekit/tree/master/plugins). +::: + + +## Native Backend Plugins + +Native Backend Plugins are the plugins that can be executed without any external service dependencies because the compute is +orchestrated by Flyte itself, within its provisioned Kubernetes clusters. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`K8s Pods ` + - Execute K8s pods for arbitrary workloads. +* - {doc}`K8s Cluster Dask Jobs ` + - Run Dask jobs on a K8s Cluster. +* - {doc}`K8s Cluster Spark Jobs ` + - Run Spark jobs on a K8s Cluster. +* - {doc}`Kubeflow PyTorch ` + - Run distributed PyTorch training jobs using `Kubeflow`. +* - {doc}`Kubeflow TensorFlow ` + - Run distributed TensorFlow training jobs using `Kubeflow`. +* - {doc}`MPI Operator ` + - Run distributed deep learning training jobs using Horovod and MPI. +* - {doc}`Ray Task ` + - Run Ray jobs on a K8s Cluster. +``` + +(external_service_backend_plugins)= + + +## External Service Backend Plugins + +As the term suggests, external service backend plugins relies on external services like +[AWS Sagemaker](https://aws.amazon.com/sagemaker), +[Hive](https://docs.qubole.com/en/latest/user-guide/engines/hive/index.html) or +[Snowflake](https://www.snowflake.com/) for handling the workload defined in +the Flyte task that use the respective plugin. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`AWS Sagemaker: Model Training ` + - Train models with built-in or define your own custom algorithms. +* - {doc}`AWS Sagemaker: Pytorch Training ` + - Train Pytorch models using Sagemaker, with support for distributed training. +* - {doc}`AWS Athena ` + - Execute queries using AWS Athena +* - {doc}`AWS Batch ` + - Running tasks and workflows on AWS batch service +* - {doc}`Hive ` + - Run Hive jobs in your workflows. +* - {doc}`MMCloud ` + - Execute tasks using MemVerge Memory Machine Cloud +* - {doc}`Snowflake ` + - Run Snowflake jobs in your workflows. +* - {doc}`Databricks ` + - Run Databricks jobs in your workflows. +* - {doc}`BigQuery ` + - Run BigQuery jobs in your workflows. +``` + +(enable-backend-plugins)= + +::::{dropdown} {fa}`info-circle` Enabling Backend Plugins +:animate: fade-in-slide-down + +To enable a backend plugin you have to add the `ID` of the plugin to the enabled plugins list. The `enabled-plugins` is available under the `tasks > task-plugins` section of FlytePropeller's configuration. +The plugin configuration structure is defined [here](https://pkg.go.dev/github.com/flyteorg/flytepropeller@v0.6.1/pkg/controller/nodes/task/config#TaskPluginConfig). An example of the config follows, + +:::{rli} https://raw.githubusercontent.com/flyteorg/flyte/master/kustomize/overlays/sandbox/flyte/config/propeller/enabled_plugins.yaml +:language: yaml +::: + +**Finding the `ID` of the Backend Plugin** + +This is a little tricky since you have to look at the source code of the plugin to figure out the `ID`. In the case of Spark, for example, the value of `ID` is used [here](https://github.com/flyteorg/flyteplugins/blob/v0.5.25/go/tasks/plugins/k8s/spark/spark.go#L424) here, defined as [spark](https://github.com/flyteorg/flyteplugins/blob/v0.5.25/go/tasks/plugins/k8s/spark/spark.go#L41). + +**Enabling a Specific Backend Plugin in Your Own Kustomize Generator** + +Flyte uses Kustomize to generate the the deployment configuration which can be leveraged to [kustomize your own deployment](https://github.com/flyteorg/flyte/tree/master/kustomize). + +:::: + + +## Custom Container Tasks + +Because Flyte uses executable docker containers as the smallest unit of compute, you can write custom tasks with the +{py:class}`flytekit.ContainerTask` via the [flytekit](https://github.com/flyteorg/flytekit) SDK. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`Raw Container Tasks ` + - Execute arbitrary containers: You can write C++ code, bash scripts and any containerized program. +``` + +## SDKs for Writing Tasks and Workflows + +The {ref}`community ` would love to help you with your own ideas of building a new SDK. Currently the available SDKs are: + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - [flytekit](https://flytekit.readthedocs.io) + - The Python SDK for Flyte. +* - [flytekit-java](https://github.com/spotify/flytekit-java) + - The Java/Scala SDK for Flyte. +``` + +## Flyte Operators + +Flyte can be integrated with other orchestrators to help you leverage Flyte's +constructs natively within other orchestration tools. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`Airflow ` + - Trigger Flyte executions from Airflow. +``` + +```{toctree} +:maxdepth: -1 +:caption: Integrations +:hidden: + +flytesnacks/examples/sql_plugin/index +flytesnacks/examples/greatexpectations_plugin/index +flytesnacks/examples/papermill_plugin/index +flytesnacks/examples/pandera_plugin/index +flytesnacks/examples/modin_plugin/index +flytesnacks/examples/dolt_plugin/index +flytesnacks/examples/dbt_plugin/index +flytesnacks/examples/whylogs_plugin/index +flytesnacks/examples/mlflow_plugin/index +flytesnacks/examples/onnx_plugin/index +flytesnacks/examples/duckdb_plugin/index +flytesnacks/examples/k8s_pod_plugin/index +flytesnacks/examples/k8s_dask_plugin/index +flytesnacks/examples/k8s_spark_plugin/index +flytesnacks/examples/kfpytorch_plugin/index +flytesnacks/examples/kftensorflow_plugin/index +flytesnacks/examples/kfmpi_plugin/index +flytesnacks/examples/ray_plugin/index +flytesnacks/examples/sagemaker_training_plugin/index +flytesnacks/examples/sagemaker_pytorch_plugin/index +flytesnacks/examples/athena_plugin/index +flytesnacks/examples/aws_batch_plugin/index +flytesnacks/examples/hive_plugin/index +flytesnacks/examples/mmcloud_plugin/index +flytesnacks/examples/snowflake_plugin/index +flytesnacks/examples/databricks_plugin/index +flytesnacks/examples/bigquery_plugin/index +flytesnacks/examples/airflow_plugin/index +``` diff --git a/docs/introduction.md b/docs/introduction.md new file mode 100644 index 0000000000..b902f32786 --- /dev/null +++ b/docs/introduction.md @@ -0,0 +1,378 @@ +--- +jupytext: + formats: md:myst + text_representation: + extension: .md + format_name: myst +kernelspec: + display_name: Python 3 + language: python + name: python3 + +# override the toc-determined page navigation order +next-page: getting_started/flyte_fundamentals +next-page-title: Flyte Fundamentals +--- + +(getting_started_index)= + +# Getting Started + +## Introduction to Flyte + +Flyte is a workflow orchestrator that seamlessly unifies data, +machine learning, and analytics stacks for building robust and reliable +applications. + +This introduction provides a quick overview of how to get Flyte up and running +on your local machine. + +````{dropdown} Want to try Flyte on the browser? +:title: text-muted +:animate: fade-in-slide-down + +The introduction below is also available on a hosted sandbox environment, where +you can get started with Flyte without installing anything locally. + +```{link-button} https://sandbox.union.ai/ +--- +classes: try-hosted-flyte btn-warning btn-block +text: Try Hosted Flyte Sandbox +--- +``` + +```{div} text-muted +*Courtesy of [Union.ai](https://www.union.ai/)* +``` + +```` + +(getting_started_installation)= + +## Installation + +```{admonition} Prerequisites +:class: important + +[Install Docker](https://docs.docker.com/get-docker/) and ensure that you +have the Docker daemon running. + +Flyte supports any [OCI-compatible](https://opencontainers.org/) container +technology (like [Podman](https://podman.io/), +[LXD](https://linuxcontainers.org/lxd/introduction/), and +[Containerd](https://containerd.io/)) when running tasks on a Flyte cluster, but +for the purpose of this guide, `flytectl` uses Docker to spin up a local +Kubernetes cluster so that you can interact with it on your machine. +``` + +First install [flytekit](https://pypi.org/project/flytekit/), Flyte's Python SDK and [Scikit-learn](https://scikit-learn.org/stable). + +```{prompt} bash $ +pip install flytekit flytekitplugins-deck-standard scikit-learn +``` + +Then install [flytectl](https://docs.flyte.org/projects/flytectl/en/latest/), +which the command-line interface for interacting with a Flyte backend. + +````{tabbed} Homebrew + +```{prompt} bash $ +brew install flyteorg/homebrew-tap/flytectl +``` + +```` + +````{tabbed} Curl + +```{prompt} bash $ +curl -sL https://ctl.flyte.org/install | sudo bash -s -- -b /usr/local/bin +``` + +```` + +## Creating a Workflow + +The first workflow we'll create is a simple model training workflow that consists +of three steps that will: + +1. 🍷 Get the classic [wine dataset](https://scikit-learn.org/stable/datasets/toy_dataset.html#wine-recognition-dataset) + using [sklearn](https://scikit-learn.org/stable/). +2. 📊 Process the data that simplifies the 3-class prediction problem into a + binary classification problem by consolidating class labels `1` and `2` into + a single class. +3. 🤖 Train a `LogisticRegression` model to learn a binary classifier. + +First, we'll define three tasks for each of these steps. Create a file called +`example.py` and copy the following code into it. + +```{code-cell} python +:tags: [remove-output] + +import pandas as pd +from sklearn.datasets import load_wine +from sklearn.linear_model import LogisticRegression + +import flytekit.extras.sklearn +from flytekit import task, workflow + + +@task +def get_data() -> pd.DataFrame: + """Get the wine dataset.""" + return load_wine(as_frame=True).frame + +@task +def process_data(data: pd.DataFrame) -> pd.DataFrame: + """Simplify the task from a 3-class to a binary classification problem.""" + return data.assign(target=lambda x: x["target"].where(x["target"] == 0, 1)) + +@task +def train_model(data: pd.DataFrame, hyperparameters: dict) -> LogisticRegression: + """Train a model on the wine dataset.""" + features = data.drop("target", axis="columns") + target = data["target"] + return LogisticRegression(max_iter=3000, **hyperparameters).fit(features, target) +``` + +As we can see in the code snippet above, we defined three tasks as Python +functions: `get_data`, `process_data`, and `train_model`. + +In Flyte, **tasks** are the most basic unit of compute and serve as the building +blocks 🧱 for more complex applications. A task is a function that takes some +inputs and produces an output. We can use these tasks to define a simple model +training workflow: + +```{code-cell} python +@workflow +def training_workflow(hyperparameters: dict) -> LogisticRegression: + """Put all of the steps together into a single workflow.""" + data = get_data() + processed_data = process_data(data=data) + return train_model( + data=processed_data, + hyperparameters=hyperparameters, + ) +``` + +```{note} +A task can also be an isolated piece of compute that takes no inputs and +produces no output, but for the most part to do something useful a task +is typically written with inputs and outputs. +``` + +A **workflow** is also defined as a Python function, and it specifies the flow +of data between tasks and, more generally, the dependencies between tasks 🔀. + +::::{dropdown} {fa}`info-circle` The code above looks like Python, but what do `@task` and `@workflow` do exactly? +:title: text-muted +:animate: fade-in-slide-down + +Flyte `@task` and `@workflow` decorators are designed to work seamlessly with +your code-base, provided that the *decorated function is at the top-level scope +of the module*. + +This means that you can invoke tasks and workflows as regular Python methods and +even import and use them in other Python modules or scripts. + +:::{note} +A {func}`task ` is a pure Python function, while a {func}`workflow ` +is actually a [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) that +only supports a subset of Python's semantics. Learn more in the +{ref}`Flyte Fundamentals ` section. +::: + +:::: + +(intro_running_flyte_workflows)= + +## Running Flyte Workflows in Python + +You can run the workflow in ``example.py`` on a local Python by using `pyflyte`, +the CLI that ships with `flytekit`. + +```{prompt} bash $ +pyflyte run example.py training_workflow \ + --hyperparameters '{"C": 0.1}' +``` + +:::::{dropdown} {fa}`info-circle` Running into shell issues? +:title: text-muted +:animate: fade-in-slide-down + +If you're using Bash, you can ignore this 🙂 +You may need to add .local/bin to your PATH variable if it's not already set, +as that's not automatically added for non-bourne shells like fish or xzsh. + +To use pyflyte, make sure to set the /.local/bin directory in PATH + +:::{code-block} fish +set -gx PATH $PATH ~/.local/bin +::: +::::: + + + +:::::{dropdown} {fa}`info-circle` Why use `pyflyte run` rather than `python example.py`? +:title: text-muted +:animate: fade-in-slide-down + +`pyflyte run` enables you to execute a specific workflow using the syntax +`pyflyte run `. + +Keyword arguments can be supplied to ``pyflyte run`` by passing in options in +the format ``--kwarg value``, and in the case of ``snake_case_arg`` argument +names, you can pass in options in the form of ``--snake-case-arg value``. + +::::{note} +If you want to run a workflow with `python example.py`, you would have to write +a `main` module conditional at the end of the script to actually run the +workflow: + +:::{code-block} python +if __name__ == "__main__": + training_workflow(hyperparameters={"C": 0.1}) +::: + +This becomes even more verbose if you want to pass in arguments: + +:::{code-block} python +if __name__ == "__main__": + import json + from argparse import ArgumentParser + + parser = ArgumentParser() + parser.add_argument("--hyperparameters", type=json.loads) + ... # add the other options + + args = parser.parse_args() + training_workflow(hyperparameters=args.hyperparameters) +::: + +:::: + +::::: + +(getting_started_flyte_cluster)= + +## Running Workflows in a Flyte Cluster + +You can also use `pyflyte run` to execute workflows on a Flyte cluster. +To do so, first spin up a local demo cluster. `flytectl` uses Docker to create +a local Kubernetes cluster and minimal Flyte backend that you can use to run +the example above: + +```{important} +Before you start the local cluster, make sure that you allocate a minimum of +`4 CPUs` and `3 GB` of memory in your Docker daemon. If you're using the +[Docker Desktop](https://www.docker.com/products/docker-desktop/), you can +do this easily by going to: + +`Settings > Resources > Advanced` + +Then set the **CPUs** and **Memory** sliders to the appropriate levels. +``` + +```{prompt} bash $ +flytectl demo start +``` + +````{div} shadow p-3 mb-8 rounded +**Expected Output:** + +```{code-block} +👨‍💻 Flyte is ready! Flyte UI is available at http://localhost:30080/console 🚀 🚀 🎉 +❇️ Run the following command to export sandbox environment variables for accessing flytectl + export FLYTECTL_CONFIG=~/.flyte/config-sandbox.yaml +🐋 Flyte sandbox ships with a Docker registry. Tag and push custom workflow images to localhost:30000 +📂 The Minio API is hosted on localhost:30002. Use http://localhost:30080/minio/login for Minio console +``` + +```{important} +Make sure to export the `FLYTECTL_CONFIG=~/.flyte/config-sandbox.yaml` environment +variable in your shell. +``` +```` + +Then, run the workflow on the Flyte cluster with `pyflyte run` using the +`--remote` flag: + +```{prompt} bash $ +pyflyte run --remote example.py training_workflow \ + --hyperparameters '{"C": 0.1}' +``` + +````{div} shadow p-3 mb-8 rounded + +**Expected Output:** A URL to the workflow execution on your demo Flyte cluster: + +```{code-block} +Go to http://localhost:30080/console/projects/flytesnacks/domains/development/executions/ to see execution in the console. +``` + +Where ```` is a unique identifier for the workflow execution. + +```` + + +## Inspect the Results + +Navigate to the URL produced by `pyflyte run`. This will take you to +FlyteConsole, the web UI used to manage Flyte entities such as tasks, +workflows, and executions. + +![getting started console](https://github.com/flyteorg/static-resources/raw/main/flytesnacks/getting_started/getting_started_console.gif) + + +```{note} +There are a few features about FlyteConsole worth pointing out in the GIF above: + +- The default execution view shows the list of tasks executing in sequential order. +- The right-hand panel shows metadata about the task execution, including logs, inputs, outputs, and task metadata. +- The **Graph** view shows the execution graph of the workflow, providing visual information about the topology + of the graph and the state of each node as the workflow progresses. +- On completion, you can inspect the outputs of each task, and ultimately, the overarching workflow. +``` + +## Summary + +🎉 **Congratulations! In this introductory guide, you:** + +1. 📜 Created a Flyte script, which trains a binary classification model. +2. 🚀 Spun up a demo Flyte cluster on your local system. +3. 👟 Ran a workflow locally and on a demo Flyte cluster. + + +## What's Next? + +Follow the rest of the sections in the documentation to get a better +understanding of the key constructs that make Flyte such a powerful +orchestration tool 💪. + +```{admonition} Recommendation +:class: tip + +If you're new to Flyte we recommend that you go through the +{ref}`Flyte Fundamentals ` and +{ref}`Core Use Cases ` section before diving +into the other sections of the documentation. +``` + +```{list-table} +:header-rows: 0 +:widths: 10 30 + +* - {ref}`🔤 Flyte Fundamentals ` + - A brief tour of the Flyte's main concepts and development lifecycle +* - {ref}`🌟 Core Use Cases ` + - An overview of core uses cases for data, machine learning, and analytics + practitioners. +* - {ref}`📖 User Guide ` + - A comprehensive view of Flyte's functionality for data scientists, + ML engineers, data engineers, and data analysts. +* - {ref}`📚 Tutorials ` + - End-to-end examples of Flyte for data/feature engineering, machine learning, + bioinformatics, and more. +* - {ref}`🚀 Deployment Guide ` + - Guides for platform engineers to deploy a Flyte cluster on your own + infrastructure. +``` diff --git a/docs/reference/index.rst b/docs/reference/index.rst new file mode 100644 index 0000000000..1e40110b0c --- /dev/null +++ b/docs/reference/index.rst @@ -0,0 +1,75 @@ +.. _reference: + +############# +API Reference +############# + +.. panels:: + :header: text-center + :column: col-lg-12 p-2 + + .. link-button:: https://flytectl.readthedocs.io + :type: url + :text: Flytectl + :classes: btn-block stretched-link + ^^^^^^^^^^^^ + The official Flyte Command-line Interface. + + --- + + .. link-button:: https://flyteidl.readthedocs.io + :type: url + :text: FlyteIDL + :classes: btn-block stretched-link + ^^^^^^^^^^^^ + The core language specification and backend service API specification for Flyte. + + --- + + .. link-button:: https://flytekit.readthedocs.io + :type: url + :text: Flytekit + :classes: btn-block stretched-link + ^^^^^^^^^^^^ + The Python SDK for Flyte. + + --- + + .. link-button:: https://github.com/spotify/flytekit-java + :type: url + :text: Flytekit-java + :classes: btn-block stretched-link + ^^^^^^^^^^^^ + The Java/Scala SDK for Flyte. + + --- + + .. link-button:: https://docs.flyte.org/projects/flyteidl/en/latest/protos/docs/service/service.html + :type: url + :text: FlyteAdmin + :classes: btn-block stretched-link + ^^^^^^^^^^^^ + Flyte Backend REST/gRPC API specification. + + --- + + .. link-button:: reference-swagger + :type: ref + :text: Flyte API Swagger Playground + :classes: btn-block stretched-link + ^^^^^^^^^^^^ + FlyteAdmin exposes a REST interface. Try out the API using an interactive environment. + + +.. toctree:: + :maxdepth: 1 + :caption: API Reference + :name: apiref + :hidden: + + FlyteCTL + FlyteIDL + Flytekit Python + Flytekit Java + FlyteAdmin + swagger diff --git a/docs/reference/swagger.rst b/docs/reference/swagger.rst new file mode 100644 index 0000000000..9344a81357 --- /dev/null +++ b/docs/reference/swagger.rst @@ -0,0 +1,31 @@ +.. _reference-swagger: + +############################# +Flyte API Playground: Swagger +############################# + +.. tags:: Basic + +Flyte services expose gRPC services for efficient/low latency communication across all services as well as for external clients (FlyteCTL, FlyteConsole, Flytekit Remote, etc.). + +The service definitions are defined `here `__. +FlyteIDL also houses open API schema definitions for the exposed services: + +- `Admin `__ +- `Auth `__ +- `Identity `__ + +To view the UI, run the following command: + +.. prompt:: bash $ + + flytectl demo start + +Once sandbox setup is complete, a ready-to-explore message is shown: + +.. prompt:: + + 👨‍💻 Flyte is ready! Flyte UI is available at http://localhost:30081/console 🚀 🚀 🎉 + + +Visit ``http://localhost:30080/api/v1/openapi`` to view the swagger documentation of the payload fields. diff --git a/docs/reference_flytectl.md b/docs/reference_flytectl.md new file mode 100644 index 0000000000..ad1ba6c7a5 --- /dev/null +++ b/docs/reference_flytectl.md @@ -0,0 +1,11 @@ +# FlyteCTL API Reference + +```{toctree} +:maxdepth: 2 + +Overview +CLI Entrypoint +flytectl/verbs +flytectl/nouns +flytectl/contribute +``` diff --git a/docs/reference_flyteidl.md b/docs/reference_flyteidl.md new file mode 100644 index 0000000000..044b902a1a --- /dev/null +++ b/docs/reference_flyteidl.md @@ -0,0 +1,18 @@ +# FlyteIDL API Reference + +The protocol buffers defined here provide a high level specification of various +entities in Flyte control plane and data plane. It provides detailed definitions +and documentation of all these entities. + +```{toctree} +:maxdepth: 2 +:name: flyteidltoc + +Flyte Core Language Specification +FlyteAdmin Service +FlyteAdmin REST and gRPC Interface +Data Catalog Service +Internal and External Eventing Interface +Flyte Task Plugin Specification +Contributing Guide +``` diff --git a/docs/reference_flytekit.md b/docs/reference_flytekit.md new file mode 100644 index 0000000000..97012a9429 --- /dev/null +++ b/docs/reference_flytekit.md @@ -0,0 +1,20 @@ +# Flytekit API Reference + +```{toctree} +:maxdepth: 2 + +api/flytekit/design/index +api/flytekit/flytekit +api/flytekit/configuration +api/flytekit/remote +api/flytekit/clients +api/flytekit/testing +api/flytekit/extend +api/flytekit/deck +api/flytekit/plugins/index +api/flytekit/tasks.extend +api/flytekit/types.extend +api/flytekit/experimental +api/flytekit/pyflyte +api/flytekit/contributing +``` diff --git a/docs/tutorials.md b/docs/tutorials.md new file mode 100644 index 0000000000..b3a3081dff --- /dev/null +++ b/docs/tutorials.md @@ -0,0 +1,96 @@ +--- +next-page: ml_training +next-page-title: Model Training +--- + +(tutorials)= + +# Tutorials + +This section showcases step-by-step case studies of how to combine the different +features of Flyte to achieve everything from data processing, feature engineering, +model training, to batch predictions. Code for all of the examples in the user +guide can be found in the [flytesnacks](https://github.com/flyteorg/flytesnacks) repo. + +It comes with a highly customized environment to make running, documenting and +contributing samples easy. If this is your first time running these examples, follow the +{ref}`setup guide ` to get started. + +```{note} +Want to contribute an example? Check out the {doc}`Example Contribution Guide `. +``` + +## 🤖 Model Training + +Train machine learning models from using your framework of choice. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`Diabetes Classification ` + - Train an XGBoost model on the Pima Indians Diabetes Dataset. +* - {doc}`House Price Regression ` + - Use dynamic workflows to train a multiregion house price prediction model using XGBoost. +* - {doc}`MNIST Classification ` + - Train a neural network on MNIST with PyTorch and W&B +* - {doc}`NLP Processing with Gensim ` + - Word embedding and topic modelling on lee background corpus with Gensim +* - {doc}`Sales Forecasting ` + - Use the Rossmann Store data to forecast sales with distributed training using Horovod on Spark. +``` + +## 🛠 Feature Engineering + +Engineer the data features to improve your model accuracy. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`EDA and Feature Engineering With Papermill ` + - How to use Jupyter notebook within Flyte +* - {doc}`Data Cleaning and Feature Serving With Feast ` + - How to use Feast to serve data in Flyte +``` + +## 🧪 Bioinformatics + +Perform computational biology with Flyte. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`Nucleotide Sequence Querying with BLASTX ` + - Use BLASTX to Query a Nucleotide Sequence Against a Local Protein Database +``` + +## 🔬 Flytelab + +The open-source repository of machine learning projects using Flyte. + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`Weather Forecasting ` + - Build an online weather forecasting application. +``` + + +```{toctree} +:maxdepth: -1 +:caption: Tutorials +:hidden: + +flytesnacks/examples/pima_diabetes/index +flytesnacks/examples/house_price_prediction/index +flytesnacks/examples/mnist_classifier/index +flytesnacks/examples/nlp_processing/index +flytesnacks/examples/forecasting_sales/index +flytesnacks/examples/exploratory_data_analysis/index +flytesnacks/examples/feast_integration/index +flytesnacks/examples/blast/index +flytesnacks/weather_forecasting +``` diff --git a/docs/userguide.md b/docs/userguide.md new file mode 100644 index 0000000000..1ab9ea4a60 --- /dev/null +++ b/docs/userguide.md @@ -0,0 +1,65 @@ +(userguide)= + +# User Guide + +If this is your first time using Flyte, check out the {doc}`Getting Started ` guide. + +This *User Guide*, the {doc}`Tutorials `, and the {doc}`Integrations ` examples cover all of +the key features of Flyte for data analytics, data science and machine learning practitioners, organized by topic. Each +section below introduces a core feature of Flyte and how you can use it to address specific use cases. Code for all +of the examples can be found in the [flytesnacks repo](https://github.com/flyteorg/flytesnacks). + +It comes with a specific environment to make running, documenting +and contributing samples easy. If this is your first time running these examples, follow the +{doc}`environment setup guide ` to get started. + +```{tip} +To learn about how to spin up and manage a Flyte cluster in the cloud, see the +{doc}`Deployment Guides `. +``` + +```{note} +Want to contribute an example? Check out the {doc}`Example Contribution Guide `. +``` + +## Table of Contents + +```{list-table} +:header-rows: 0 +:widths: 20 30 + +* - {doc}`🌳 Environment Setup ` + - Set up a development environment to run the examples in the user guide. +* - {doc}`🔤 Basics ` + - Learn about tasks, workflows, launch plans, caching and managing files and directories. +* - {doc}`⌨️ Data Types and IO ` + - Improve pipeline robustness with Flyte's portable and extensible type system. +* - {doc}`🔮 Advanced Composition ` + - Implement conditionals, nested and dynamic workflows, map tasks and even recursion! +* - {doc}`🧩 Customizing Dependencies ` + - Provide custom dependencies to run your Flyte entities. +* - {doc}`🏡 Development Lifecycle ` + - Develop and test locally on the demo cluster. +* - {doc}`⚗️ Testing ` + - Test tasks and workflows with Flyte's testing utilities. +* - {doc}`🚢 Productionizing ` + - Ship and configure your machine learning pipelines on a production Flyte installation. +* - {doc}`🏗 Extending ` + - Define custom plugins that aren't currently supported in the Flyte ecosystem. +``` + +```{toctree} +:maxdepth: -1 +:caption: User Guide +:hidden: + +Environment Setup +Basics +Data Types and IO +Advanced Composition +Customizing Dependencies +Development Lifecycle +Testing +Productionizing +Extending +``` diff --git a/monodocs-environment.yaml b/monodocs-environment.yaml new file mode 100644 index 0000000000..335f8584e4 --- /dev/null +++ b/monodocs-environment.yaml @@ -0,0 +1,73 @@ +channels: + - conda-forge +dependencies: + - python=3.9 + - pip + - codespell + - furo + - flytekit + - gitpython + - ipython!=8.7.0 + - graphviz + - jupytext + - myst-nb + - psycopg2-binary + - recommonmark + - sphinx==4.5.0 + - sphinx-prompt + - sphinx-click + - sphinx-autoapi + - sphinx-copybutton + - sphinx-issues + - sphinx_fontawesome + - sphinx-panels + - sphinxcontrib-mermaid + - sphinxcontrib-youtube==1.2.0 + - sphinx-tabs + - sphinx-tags==0.2.1 + + # Packages for Plugin docs + # Package name Plugin needing it + - retry # aws sagemaker + - botocore # fsspec + - fsspec # fsspec + - google-cloud-bigquery # bigquery + - markdown # deck + - plotly # deck + - great-expectations # greatexpectations + - datasets # huggingface + - kubernetes # k8s-pod + - modin # modin + - pandera # pandera + - pydantic # vaex, pydantic + - papermill # papermill + - jupyter # papermill + - polars # polars + - pyspark # spark + - sqlalchemy # sqlalchemy + - pytorch # pytorch + - skl2onnx # onnxscikitlearn + - numpy==1.23.5 # onnxtensorflow numpy.bool warning + - tf2onnx # onnxtensorflow + - tensorflow>=2.13.0 # onnxtensorflow + - scikit-learn # scikit-learn + - dask[distributed] # dask + - mlflow==2.7.0 # mlflow + - snowflake-connector-python # snowflake + - vaex-core # vaex + + - pip: + - sphinx-code-include + - sphinxext-remoteliteralinclude + - sphinx_markdown_tables + - sphinxcontrib-video + - flytekitplugins-deck-standard + - flytekitplugins-kfpytorch + - flytekitplugins-sqlalchemy + - dolt_integrations + - google-cloud + - ydata_profiling + - whylogs==1.3.3 # whylogs + - whylabs-client # whylogs + - ray==2.6.3 + - duckdb diff --git a/rfc/system/2704-release-cycle-process-updates.md b/rfc/system/2704-release-cycle-process-updates.md index 752ff7c7b7..9583d19467 100644 --- a/rfc/system/2704-release-cycle-process-updates.md +++ b/rfc/system/2704-release-cycle-process-updates.md @@ -3,7 +3,7 @@ Hack MD: https://hackmd.io/ZwarNg5iSjeJz2l0YBKIZQ ## Background & Issues -This is the current [roadmap](https://github.com/flyteorg/flyte/blob/master/rsts/community/roadmap.rst). The core Flyte maintainers team is proposing some updates to it, specifically to the Milestones and Releases section. +This is the current [roadmap](https://github.com/flyteorg/flyte/blob/master/docs/community/roadmap.rst). The core Flyte maintainers team is proposing some updates to it, specifically to the Milestones and Releases section. We are proposing: * Changes to the pace of Flyte releases. @@ -78,7 +78,7 @@ We decided that this approach was less desirable because: Whether or not a patch version of any of the Flyte components also creates a Flyte patch release shall be left to the discretion of the developer. ### Documentation Versioning -We also currently have an issue with our documentation versioning. While our readthedocs page does have versioning enabled and we publish the [docs version](https://github.com/flyteorg/flyte/blob/80c098f10334b1c916d1e4274ab9f204152d9d80/rsts/conf.py#L33), all the [intersphinx mappings](https://github.com/flyteorg/flyte/blob/80c098f10334b1c916d1e4274ab9f204152d9d80/rsts/conf.py#L219) just point to `latest`. Keep in mind that this mapping not only exists in this `flyte` repo, but also in all the other repos that that mapping points to. That is, to maintain an accurate mapping of different versions of documentation, we'll need to update the mapping in all the repos. +We also currently have an issue with our documentation versioning. While our readthedocs page does have versioning enabled and we publish the [docs version](https://github.com/flyteorg/flyte/blob/80c098f10334b1c916d1e4274ab9f204152d9d80/docs/conf.py#L33), all the [intersphinx mappings](https://github.com/flyteorg/flyte/blob/80c098f10334b1c916d1e4274ab9f204152d9d80/docs/conf.py#L219) just point to `latest`. Keep in mind that this mapping not only exists in this `flyte` repo, but also in all the other repos that that mapping points to. That is, to maintain an accurate mapping of different versions of documentation, we'll need to update the mapping in all the repos. To remediate this, we propose the following: * Documentation should be pinned only to Major.Minor on all the repos that have their versions "aligned". diff --git a/rsts/deployment/deployment/sandbox.rst b/rsts/deployment/deployment/sandbox.rst index ad99cf7d48..970d001fb5 100644 --- a/rsts/deployment/deployment/sandbox.rst +++ b/rsts/deployment/deployment/sandbox.rst @@ -140,6 +140,5 @@ You can also specify additional cluster resource templates in the ``~/.flyte/san Once you are happy with the changes, simply run ``flytectl demo reload`` to trigger a reload of the sandbox with the updated configuration. - Now that you have the sandbox cluster running, you can now go to the :ref:`User Guide ` or :ref:`Tutorials ` to run tasks and workflows written in ``flytekit``, the Python SDK for Flyte. diff --git a/script/generate_config_docs.sh b/script/generate_config_docs.sh index 1170979b2f..2a1485aed8 100755 --- a/script/generate_config_docs.sh +++ b/script/generate_config_docs.sh @@ -5,7 +5,7 @@ set -e echo "Generating Flyte Configuration Documents" CUR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" ROOT_DIR=${CUR_DIR}/.. -OUTPUT_DIR="${ROOT_DIR}"/rsts/deployment/configuration/generated +OUTPUT_DIR="${ROOT_DIR}"/docs/deployment/configuration/generated GOBIN=${GOPATH:-~/go}/bin make -C datacatalog compile diff --git a/script/generate_docs.sh b/script/generate_docs.sh index 25ebf8a1a2..c6df439f8f 100755 --- a/script/generate_docs.sh +++ b/script/generate_docs.sh @@ -15,8 +15,8 @@ mkdir ${BASEDIR}/rsts_tmp || true RSTS_DIR=`mktemp -d "${BASEDIR}/rsts_tmp/XXXXXXXXX"` # Copy all rst files to the same place -cp -R rsts/* ${RSTS_DIR} -cp -R _rsts/* ${RSTS_DIR} +cp -R docs/* ${RSTS_DIR} +cp -R docs/* ${RSTS_DIR} # Generate documentation by running script inside the generation container docker run --rm -t -e FLYTEKIT_VERSION=${FLYTEKIT_VERSION} -v ${BASEDIR}:/base -v ${BASEDIR}/docs:/docs -v ${RSTS_DIR}:/rsts ghcr.io/nuclyde-io/docbuilder:e70cfafe3397c3b23d11183973c0f44e0024f025 /base/docs_infra/in_container_html_generation.sh From 94d79f5db6011b6fbae060b91725412bd238a3ab Mon Sep 17 00:00:00 2001 From: Thomas Newton Date: Wed, 6 Dec 2023 16:20:45 +0000 Subject: [PATCH 10/19] [Spark plugin] Fix environment variable ValueFrom for pod templates (#4532) * Update tests Signed-off-by: Thomas Newton * Use Copy Container.Env to SparkPodSpec.Env instead of SparkPodSpec.EnvVars Signed-off-by: Thomas Newton * Fix list initialisation Signed-off-by: Thomas Newton --------- Signed-off-by: Thomas Newton Co-authored-by: Dan Rammer --- .../go/tasks/plugins/k8s/spark/spark.go | 8 ++-- .../go/tasks/plugins/k8s/spark/spark_test.go | 47 ++++++++++++++----- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/flyteplugins/go/tasks/plugins/k8s/spark/spark.go b/flyteplugins/go/tasks/plugins/k8s/spark/spark.go index defcb275fe..22240e9e45 100644 --- a/flyteplugins/go/tasks/plugins/k8s/spark/spark.go +++ b/flyteplugins/go/tasks/plugins/k8s/spark/spark.go @@ -145,17 +145,17 @@ func createSparkPodSpec(taskCtx pluginsCore.TaskExecutionContext, podSpec *v1.Po annotations := utils.UnionMaps(config.GetK8sPluginConfig().DefaultAnnotations, utils.CopyMap(taskCtx.TaskExecutionMetadata().GetAnnotations())) labels := utils.UnionMaps(config.GetK8sPluginConfig().DefaultLabels, utils.CopyMap(taskCtx.TaskExecutionMetadata().GetLabels())) - sparkEnvVars := make(map[string]string) + sparkEnv := make([]v1.EnvVar, 0) for _, envVar := range container.Env { - sparkEnvVars[envVar.Name] = envVar.Value + sparkEnv = append(sparkEnv, *envVar.DeepCopy()) } - sparkEnvVars["FLYTE_MAX_ATTEMPTS"] = strconv.Itoa(int(taskCtx.TaskExecutionMetadata().GetMaxAttempts())) + sparkEnv = append(sparkEnv, v1.EnvVar{Name: "FLYTE_MAX_ATTEMPTS", Value: strconv.Itoa(int(taskCtx.TaskExecutionMetadata().GetMaxAttempts()))}) spec := sparkOp.SparkPodSpec{ Affinity: podSpec.Affinity, Annotations: annotations, Labels: labels, - EnvVars: sparkEnvVars, + Env: sparkEnv, Image: &container.Image, SecurityContenxt: podSpec.SecurityContext.DeepCopy(), DNSConfig: podSpec.DNSConfig.DeepCopy(), diff --git a/flyteplugins/go/tasks/plugins/k8s/spark/spark_test.go b/flyteplugins/go/tasks/plugins/k8s/spark/spark_test.go index be2f9477b6..b07ab0ef33 100644 --- a/flyteplugins/go/tasks/plugins/k8s/spark/spark_test.go +++ b/flyteplugins/go/tasks/plugins/k8s/spark/spark_test.go @@ -49,6 +49,18 @@ var ( {Key: "Env_Var", Value: "Env_Val"}, } + dummyEnvVarsWithSecretRef = []corev1.EnvVar{ + {Name: "Env_Var", Value: "Env_Val"}, + {Name: "SECRET", ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + Key: "key", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "secret-name", + }, + }, + }}, + } + testArgs = []string{ "execute-spark-task", } @@ -261,7 +273,7 @@ func dummyPodSpec() *corev1.PodSpec { Name: "primary", Image: testImage, Args: testArgs, - Env: flytek8s.ToK8sEnvVar(dummyEnvVars), + Env: dummyEnvVarsWithSecretRef, }, { Name: "secondary", @@ -512,6 +524,15 @@ func defaultPluginConfig() *config.K8sPluginConfig { return config } +func findEnvVarByName(envVars []corev1.EnvVar, name string) *corev1.EnvVar { + for _, envVar := range envVars { + if envVar.Name == name { + return &envVar + } + } + return nil +} + func TestBuildResourceContainer(t *testing.T) { sparkResourceHandler := sparkResourceHandler{} @@ -639,11 +660,11 @@ func TestBuildResourceContainer(t *testing.T) { assert.Greater(t, len(sparkApp.Spec.SparkConf["spark.kubernetes.driverEnv.FLYTE_START_TIME"]), 1) assert.Equal(t, dummySparkConf["spark.flyteorg.feature3.enabled"], sparkApp.Spec.SparkConf["spark.flyteorg.feature3.enabled"]) - assert.Equal(t, len(sparkApp.Spec.Driver.EnvVars["FLYTE_MAX_ATTEMPTS"]), 1) - assert.Equal(t, defaultConfig.DefaultEnvVars["foo"], sparkApp.Spec.Driver.EnvVars["foo"]) - assert.Equal(t, defaultConfig.DefaultEnvVars["foo"], sparkApp.Spec.Executor.EnvVars["foo"]) - assert.Equal(t, defaultConfig.DefaultEnvVars["fooEnv"], sparkApp.Spec.Driver.EnvVars["fooEnv"]) - assert.Equal(t, defaultConfig.DefaultEnvVars["fooEnv"], sparkApp.Spec.Executor.EnvVars["fooEnv"]) + assert.Equal(t, len(findEnvVarByName(sparkApp.Spec.Driver.Env, "FLYTE_MAX_ATTEMPTS").Value), 1) + assert.Equal(t, defaultConfig.DefaultEnvVars["foo"], findEnvVarByName(sparkApp.Spec.Driver.Env, "foo").Value) + assert.Equal(t, defaultConfig.DefaultEnvVars["foo"], findEnvVarByName(sparkApp.Spec.Executor.Env, "foo").Value) + assert.Equal(t, defaultConfig.DefaultEnvVars["fooEnv"], findEnvVarByName(sparkApp.Spec.Driver.Env, "fooEnv").Value) + assert.Equal(t, defaultConfig.DefaultEnvVars["fooEnv"], findEnvVarByName(sparkApp.Spec.Executor.Env, "fooEnv").Value) assert.Equal(t, &corev1.NodeAffinity{ RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ @@ -789,9 +810,11 @@ func TestBuildResourcePodTemplate(t *testing.T) { // Driver assert.Equal(t, utils.UnionMaps(defaultConfig.DefaultAnnotations, map[string]string{"annotation-1": "val1"}), sparkApp.Spec.Driver.Annotations) assert.Equal(t, utils.UnionMaps(defaultConfig.DefaultLabels, map[string]string{"label-1": "val1"}), sparkApp.Spec.Driver.Labels) - assert.Equal(t, len(sparkApp.Spec.Driver.EnvVars["FLYTE_MAX_ATTEMPTS"]), 1) - assert.Equal(t, defaultConfig.DefaultEnvVars["foo"], sparkApp.Spec.Driver.EnvVars["foo"]) - assert.Equal(t, defaultConfig.DefaultEnvVars["fooEnv"], sparkApp.Spec.Driver.EnvVars["fooEnv"]) + assert.Equal(t, len(findEnvVarByName(sparkApp.Spec.Driver.Env, "FLYTE_MAX_ATTEMPTS").Value), 1) + assert.Equal(t, defaultConfig.DefaultEnvVars["foo"], findEnvVarByName(sparkApp.Spec.Driver.Env, "foo").Value) + assert.Equal(t, defaultConfig.DefaultEnvVars["fooEnv"], findEnvVarByName(sparkApp.Spec.Driver.Env, "fooEnv").Value) + assert.Equal(t, findEnvVarByName(dummyEnvVarsWithSecretRef, "SECRET"), findEnvVarByName(sparkApp.Spec.Driver.Env, "SECRET")) + assert.Equal(t, 9, len(sparkApp.Spec.Driver.Env)) assert.Equal(t, testImage, *sparkApp.Spec.Driver.Image) assert.Equal(t, flytek8s.GetServiceAccountNameFromTaskExecutionMetadata(taskCtx.TaskExecutionMetadata()), *sparkApp.Spec.Driver.ServiceAccount) assert.Equal(t, defaultConfig.DefaultPodSecurityContext, sparkApp.Spec.Driver.SecurityContenxt) @@ -825,8 +848,10 @@ func TestBuildResourcePodTemplate(t *testing.T) { // Executor assert.Equal(t, utils.UnionMaps(defaultConfig.DefaultAnnotations, map[string]string{"annotation-1": "val1"}), sparkApp.Spec.Executor.Annotations) assert.Equal(t, utils.UnionMaps(defaultConfig.DefaultLabels, map[string]string{"label-1": "val1"}), sparkApp.Spec.Executor.Labels) - assert.Equal(t, defaultConfig.DefaultEnvVars["foo"], sparkApp.Spec.Executor.EnvVars["foo"]) - assert.Equal(t, defaultConfig.DefaultEnvVars["fooEnv"], sparkApp.Spec.Executor.EnvVars["fooEnv"]) + assert.Equal(t, defaultConfig.DefaultEnvVars["foo"], findEnvVarByName(sparkApp.Spec.Executor.Env, "foo").Value) + assert.Equal(t, defaultConfig.DefaultEnvVars["fooEnv"], findEnvVarByName(sparkApp.Spec.Executor.Env, "fooEnv").Value) + assert.Equal(t, findEnvVarByName(dummyEnvVarsWithSecretRef, "SECRET"), findEnvVarByName(sparkApp.Spec.Executor.Env, "SECRET")) + assert.Equal(t, 9, len(sparkApp.Spec.Executor.Env)) assert.Equal(t, testImage, *sparkApp.Spec.Executor.Image) assert.Equal(t, defaultConfig.DefaultPodSecurityContext, sparkApp.Spec.Executor.SecurityContenxt) assert.Equal(t, defaultConfig.DefaultPodDNSConfig, sparkApp.Spec.Executor.DNSConfig) From 040a05ff9e20d5643d963f2b8a045c2d875fe7d8 Mon Sep 17 00:00:00 2001 From: Dan Rammer Date: Wed, 6 Dec 2023 10:36:40 -0600 Subject: [PATCH 11/19] bypassing cache lookup when node is in predicatephase (#4524) Signed-off-by: Daniel Rammer --- flytepropeller/pkg/controller/nodes/executor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flytepropeller/pkg/controller/nodes/executor.go b/flytepropeller/pkg/controller/nodes/executor.go index 5e1cbe4f51..8e96ee9645 100644 --- a/flytepropeller/pkg/controller/nodes/executor.go +++ b/flytepropeller/pkg/controller/nodes/executor.go @@ -941,7 +941,7 @@ func (c *nodeExecutor) handleNotYetStartedNode(ctx context.Context, dag executor } var cacheStatus *catalog.Status - if cacheHandler, ok := h.(interfaces.CacheableNodeHandler); ok { + if cacheHandler, ok := h.(interfaces.CacheableNodeHandler); p.GetPhase() != handler.EPhaseSkip && ok { cacheable, _, err := cacheHandler.IsCacheable(ctx, nCtx) if err != nil { logger.Errorf(ctx, "failed to determine if node is cacheable with err '%s'", err.Error()) From 9423d1fc87769b7ef0ca2f71ba9c7e80522b072c Mon Sep 17 00:00:00 2001 From: Dan Rammer Date: Wed, 6 Dec 2023 11:58:09 -0600 Subject: [PATCH 12/19] removed composition error from branch node (#4528) Signed-off-by: Daniel Rammer --- .../pkg/apis/flyteworkflow/v1alpha1/branch.go | 42 +++---------------- .../flyteworkflow/v1alpha1/branch_test.go | 23 +--------- .../v1alpha1/zz_generated.deepcopy.go | 12 +----- ...rol_flow.conditions.multiplier_2_2_wf.yaml | 2 +- ...rol_flow.conditions.multiplier_3_2_wf.yaml | 2 +- ...low.conditions.nested_conditions_2_wf.yaml | 2 +- .../pkg/compiler/transformers/k8s/node.go | 2 +- .../controller/nodes/branch/evaluator_test.go | 6 +-- flytepropeller/pkg/webhook/config/config.go | 3 +- flytepropeller/pkg/webhook/entrypoint.go | 3 +- flytepropeller/pkg/webhook/pod.go | 2 +- 11 files changed, 18 insertions(+), 81 deletions(-) diff --git a/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/branch.go b/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/branch.go index 07a493b8be..37a54dfffe 100644 --- a/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/branch.go +++ b/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/branch.go @@ -8,35 +8,6 @@ import ( "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core" ) -type Error struct { - *core.Error -} - -func (in Error) UnmarshalJSON(b []byte) error { - in.Error = &core.Error{} - return jsonpb.Unmarshal(bytes.NewReader(b), in.Error) -} - -func (in Error) MarshalJSON() ([]byte, error) { - if in.Error == nil { - return nilJSON, nil - } - - var buf bytes.Buffer - if err := marshaler.Marshal(&buf, in.Error); err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Error) DeepCopyInto(out *Error) { - *out = *in - // We do not manipulate the object, so its ok - // Once we figure out the autogenerate story we can replace this - -} - type BooleanExpression struct { *core.BooleanExpression } @@ -79,10 +50,10 @@ func (in *IfBlock) GetThenNode() *NodeID { } type BranchNodeSpec struct { - If IfBlock `json:"if"` - ElseIf []*IfBlock `json:"elseIf,omitempty"` - Else *NodeID `json:"else,omitempty"` - ElseFail *Error `json:"elseFail,omitempty"` + If IfBlock `json:"if"` + ElseIf []*IfBlock `json:"elseIf,omitempty"` + Else *NodeID `json:"else,omitempty"` + ElseFail *core.Error `json:"elseFail,omitempty"` } func (in *BranchNodeSpec) GetIf() ExecutableIfBlock { @@ -102,8 +73,5 @@ func (in *BranchNodeSpec) GetElseIf() []ExecutableIfBlock { } func (in *BranchNodeSpec) GetElseFail() *core.Error { - if in.ElseFail != nil { - return in.ElseFail.Error - } - return nil + return in.ElseFail } diff --git a/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/branch_test.go b/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/branch_test.go index 5fe19f6758..5fd2a14218 100644 --- a/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/branch_test.go +++ b/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/branch_test.go @@ -1,12 +1,10 @@ package v1alpha1 import ( - "bytes" "encoding/json" "io/ioutil" "testing" - "github.com/golang/protobuf/jsonpb" "github.com/stretchr/testify/assert" "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core" @@ -27,25 +25,6 @@ func TestMarshalUnMarshal_BranchTask(t *testing.T) { } } -// TestBranchNodeSpecMethods tests the methods of the BranchNodeSpec struct. -func TestErrorMarshalAndUnmarshalJSON(t *testing.T) { - coreError := &core.Error{ - FailedNodeId: "TestNode", - Message: "Test error message", - } - - err := Error{Error: coreError} - data, jErr := err.MarshalJSON() - assert.Nil(t, jErr) - - // Unmarshalling the JSON back to a new core.Error struct - var newCoreError core.Error - uErr := jsonpb.Unmarshal(bytes.NewReader(data), &newCoreError) - assert.Nil(t, uErr) - assert.Equal(t, coreError.Message, newCoreError.Message) - assert.Equal(t, coreError.FailedNodeId, newCoreError.FailedNodeId) -} - func TestBranchNodeSpecMethods(t *testing.T) { // Creating a core.BooleanExpression instance for testing boolExpr := &core.BooleanExpression{} @@ -76,7 +55,7 @@ func TestBranchNodeSpecMethods(t *testing.T) { }, }, Else: &elseNode, - ElseFail: &Error{Error: errorMessage}, + ElseFail: errorMessage, } assert.Equal(t, boolExpr, branchNodeSpec.If.GetCondition()) diff --git a/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/zz_generated.deepcopy.go b/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/zz_generated.deepcopy.go index 80d1f04427..febbca733c 100644 --- a/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/zz_generated.deepcopy.go +++ b/flytepropeller/pkg/apis/flyteworkflow/v1alpha1/zz_generated.deepcopy.go @@ -64,7 +64,7 @@ func (in *BranchNodeSpec) DeepCopyInto(out *BranchNodeSpec) { } if in.ElseFail != nil { in, out := &in.ElseFail, &out.ElseFail - *out = (*in).DeepCopy() + *out = *in } return } @@ -142,16 +142,6 @@ func (in *DynamicNodeStatus) DeepCopy() *DynamicNodeStatus { return out } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Error. -func (in *Error) DeepCopy() *Error { - if in == nil { - return nil - } - out := new(Error) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExecutionConfig) DeepCopyInto(out *ExecutionConfig) { *out = *in diff --git a/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/028_core.control_flow.conditions.multiplier_2_2_wf.yaml b/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/028_core.control_flow.conditions.multiplier_2_2_wf.yaml index 7ec08f7c34..54fb0413d5 100755 --- a/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/028_core.control_flow.conditions.multiplier_2_2_wf.yaml +++ b/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/028_core.control_flow.conditions.multiplier_2_2_wf.yaml @@ -76,7 +76,7 @@ spec: n0: branch: elseFail: - failedNodeId: fractions + failed_node_id: fractions message: The input must be between 0 and 10 elseIf: - condition: diff --git a/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/030_core.control_flow.conditions.multiplier_3_2_wf.yaml b/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/030_core.control_flow.conditions.multiplier_3_2_wf.yaml index 10d028fa4a..07c632c8e0 100755 --- a/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/030_core.control_flow.conditions.multiplier_3_2_wf.yaml +++ b/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/030_core.control_flow.conditions.multiplier_3_2_wf.yaml @@ -82,7 +82,7 @@ spec: n0: branch: elseFail: - failedNodeId: fractions + failed_node_id: fractions message: The input must be between 0 and 10 elseIf: - condition: diff --git a/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/039_core.control_flow.conditions.nested_conditions_2_wf.yaml b/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/039_core.control_flow.conditions.nested_conditions_2_wf.yaml index 8579f95947..abfc362b09 100755 --- a/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/039_core.control_flow.conditions.nested_conditions_2_wf.yaml +++ b/flytepropeller/pkg/compiler/test/testdata/snacks-core/k8s/039_core.control_flow.conditions.nested_conditions_2_wf.yaml @@ -135,7 +135,7 @@ spec: n0-n0: branch: elseFail: - failedNodeId: inner_fractions + failed_node_id: inner_fractions message: Only <0.7 allowed elseIf: - condition: diff --git a/flytepropeller/pkg/compiler/transformers/k8s/node.go b/flytepropeller/pkg/compiler/transformers/k8s/node.go index 2ac06ebd89..7120f3ad90 100644 --- a/flytepropeller/pkg/compiler/transformers/k8s/node.go +++ b/flytepropeller/pkg/compiler/transformers/k8s/node.go @@ -229,7 +229,7 @@ func buildBranchNodeSpec(branch *core.BranchNode, tasks []*core.CompiledTask, er childNodes = append(childNodes, ns...) res.Else = refStr(branch.IfElse.GetElseNode().Id) case *core.IfElseBlock_Error: - res.ElseFail = &v1alpha1.Error{Error: branch.IfElse.GetError()} + res.ElseFail = branch.IfElse.GetError() } other := make([]*v1alpha1.IfBlock, 0, len(branch.IfElse.Other)) diff --git a/flytepropeller/pkg/controller/nodes/branch/evaluator_test.go b/flytepropeller/pkg/controller/nodes/branch/evaluator_test.go index 45bb850358..dae8a1337b 100644 --- a/flytepropeller/pkg/controller/nodes/branch/evaluator_test.go +++ b/flytepropeller/pkg/controller/nodes/branch/evaluator_test.go @@ -672,10 +672,8 @@ func TestDecideBranch(t *testing.T) { ThenNode: &n2, }, }, - ElseFail: &v1alpha1.Error{ - Error: &core.Error{ - Message: userError, - }, + ElseFail: &core.Error{ + Message: userError, }, } diff --git a/flytepropeller/pkg/webhook/config/config.go b/flytepropeller/pkg/webhook/config/config.go index a1a6fd94ae..71e901ad5b 100644 --- a/flytepropeller/pkg/webhook/config/config.go +++ b/flytepropeller/pkg/webhook/config/config.go @@ -1,9 +1,10 @@ package config import ( + "os" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - "os" "github.com/flyteorg/flyte/flytestdlib/config" ) diff --git a/flytepropeller/pkg/webhook/entrypoint.go b/flytepropeller/pkg/webhook/entrypoint.go index ad2c21d6a1..1433c52689 100644 --- a/flytepropeller/pkg/webhook/entrypoint.go +++ b/flytepropeller/pkg/webhook/entrypoint.go @@ -5,10 +5,11 @@ import ( "encoding/json" errors2 "errors" "fmt" + "os" + "k8s.io/apimachinery/pkg/api/errors" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "os" "sigs.k8s.io/controller-runtime/pkg/manager" "github.com/flyteorg/flyte/flytepropeller/pkg/controller/config" diff --git a/flytepropeller/pkg/webhook/pod.go b/flytepropeller/pkg/webhook/pod.go index 144c9f0a50..9e3a300bf6 100644 --- a/flytepropeller/pkg/webhook/pod.go +++ b/flytepropeller/pkg/webhook/pod.go @@ -31,7 +31,6 @@ import ( "context" "encoding/json" "fmt" - "k8s.io/apimachinery/pkg/runtime" "net/http" "os" "path/filepath" @@ -40,6 +39,7 @@ import ( admissionregistrationv1 "k8s.io/api/admissionregistration/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" From 2105f099652b09adc0460bf6f9da0453251e34f1 Mon Sep 17 00:00:00 2001 From: Niels Bantilan Date: Wed, 6 Dec 2023 13:24:41 -0500 Subject: [PATCH 13/19] ignore warnings related to awssagemaker import (#4540) Signed-off-by: Niels Bantilan Co-authored-by: Eduardo Apolinario <653394+eapolinario@users.noreply.github.com> --- docs/conf.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index b8581c49bf..904e216bfa 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -426,11 +426,14 @@ def __init__(self, app: sphinx.application.Sphinx) -> None: def filter(self, record: logging.LogRecord) -> bool: msg = record.getMessage() + # TODO: These are all warnings that should be fixed as follow-ups to the + # monodocs build project. filter_out = ( "duplicate label", "Unexpected indentation", 'Error with CSV data in "csv-table" directive', "Definition list ends without a blank line", + "autodoc: failed to import module 'awssagemaker' from module 'flytekitplugins'", ) if msg.strip().startswith(filter_out): From 25531535a39ca66a915e45b2d6f32251e4c547f3 Mon Sep 17 00:00:00 2001 From: Paul Dittamo <37558497+pvditt@users.noreply.github.com> Date: Wed, 6 Dec 2023 12:04:59 -0800 Subject: [PATCH 14/19] [BUG] Fix setting of service_account from PodTemplate (#4536) * don't override service account from security context if already set Signed-off-by: Paul Dittamo * update unit test Signed-off-by: Paul Dittamo * cleanup Signed-off-by: Paul Dittamo * typo Signed-off-by: Paul Dittamo * clean up sytling Signed-off-by: Paul Dittamo --------- Signed-off-by: Paul Dittamo Co-authored-by: Dan Rammer --- .../tasks/plugins/k8s/pod/container_test.go | 122 ++++++++++++++---- .../go/tasks/plugins/k8s/pod/plugin.go | 4 +- 2 files changed, 101 insertions(+), 25 deletions(-) diff --git a/flyteplugins/go/tasks/plugins/k8s/pod/container_test.go b/flyteplugins/go/tasks/plugins/k8s/pod/container_test.go index 19000e0c72..9a70f906b9 100644 --- a/flyteplugins/go/tasks/plugins/k8s/pod/container_test.go +++ b/flyteplugins/go/tasks/plugins/k8s/pod/container_test.go @@ -19,6 +19,7 @@ import ( flytek8sConfig "github.com/flyteorg/flyte/flyteplugins/go/tasks/pluginmachinery/flytek8s/config" pluginsIOMock "github.com/flyteorg/flyte/flyteplugins/go/tasks/pluginmachinery/io/mocks" "github.com/flyteorg/flyte/flyteplugins/go/tasks/pluginmachinery/k8s" + "github.com/flyteorg/flyte/flyteplugins/go/tasks/pluginmachinery/utils" ) var containerResourceRequirements = &v1.ResourceRequirements{ @@ -28,6 +29,12 @@ var containerResourceRequirements = &v1.ResourceRequirements{ }, } +var ( + serviceAccount = "service-account" + podTemplateServiceAccount = "test-service-account" + securityContextServiceAccount = "security-context-service-account" +) + func dummyContainerTaskTemplate(command []string, args []string) *core.TaskTemplate { return &core.TaskTemplate{ Type: "test", @@ -40,7 +47,40 @@ func dummyContainerTaskTemplate(command []string, args []string) *core.TaskTempl } } -func dummyContainerTaskMetadata(resources *v1.ResourceRequirements, extendedResources *core.ExtendedResources) pluginsCore.TaskExecutionMetadata { +func dummyContainerTaskTemplateWithPodSpec(command []string, args []string) *core.TaskTemplate { + + podSpec := v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Name: "test-image", + Command: command, + Args: args, + }, + }, + ServiceAccountName: podTemplateServiceAccount, + } + + podSpecPb, err := utils.MarshalObjToStruct(podSpec) + if err != nil { + panic(err) + } + + taskTemplate := &core.TaskTemplate{ + Type: "test", + Target: &core.TaskTemplate_K8SPod{ + K8SPod: &core.K8SPod{ + PodSpec: podSpecPb, + }, + }, + Config: map[string]string{ + "primary_container_name": "test-image", + }, + } + + return taskTemplate +} + +func dummyContainerTaskMetadata(resources *v1.ResourceRequirements, extendedResources *core.ExtendedResources, returnsServiceAccount bool) pluginsCore.TaskExecutionMetadata { taskMetadata := &pluginsCoreMock.TaskExecutionMetadata{} taskMetadata.On("GetNamespace").Return("test-namespace") taskMetadata.On("GetAnnotations").Return(map[string]string{"annotation-1": "val1"}) @@ -49,9 +89,13 @@ func dummyContainerTaskMetadata(resources *v1.ResourceRequirements, extendedReso Kind: "node", Name: "blah", }) - taskMetadata.On("GetK8sServiceAccount").Return("service-account") + if returnsServiceAccount { + taskMetadata.On("GetK8sServiceAccount").Return(serviceAccount) + } else { + taskMetadata.On("GetK8sServiceAccount").Return("") + } taskMetadata.On("GetSecurityContext").Return(core.SecurityContext{ - RunAs: &core.Identity{K8SServiceAccount: "service-account"}, + RunAs: &core.Identity{K8SServiceAccount: securityContextServiceAccount}, }) taskMetadata.On("GetOwnerID").Return(types.NamespacedName{ Namespace: "test-namespace", @@ -81,8 +125,7 @@ func dummyContainerTaskMetadata(resources *v1.ResourceRequirements, extendedReso return taskMetadata } -func dummyContainerTaskContext(taskTemplate *core.TaskTemplate, resources *v1.ResourceRequirements, extendedResources *core.ExtendedResources) pluginsCore.TaskExecutionContext { - dummyTaskMetadata := dummyContainerTaskMetadata(resources, extendedResources) +func dummyContainerTaskContext(taskTemplate *core.TaskTemplate, taskMetadata pluginsCore.TaskExecutionMetadata) pluginsCore.TaskExecutionContext { taskCtx := &pluginsCoreMock.TaskExecutionContext{} inputReader := &pluginsIOMock.InputReader{} inputReader.OnGetInputPrefixPath().Return("test-data-reference") @@ -103,7 +146,7 @@ func dummyContainerTaskContext(taskTemplate *core.TaskTemplate, resources *v1.Re taskReader.OnReadMatch(mock.Anything).Return(taskTemplate, nil) taskCtx.OnTaskReader().Return(taskReader) - taskCtx.OnTaskExecutionMetadata().Return(dummyTaskMetadata) + taskCtx.OnTaskExecutionMetadata().Return(taskMetadata) pluginStateReader := &pluginsCoreMock.PluginStateReader{} pluginStateReader.OnGetMatch(mock.Anything).Return(0, nil) @@ -125,26 +168,54 @@ func TestContainerTaskExecutor_BuildIdentityResource(t *testing.T) { func TestContainerTaskExecutor_BuildResource(t *testing.T) { command := []string{"command"} args := []string{"{{.Input}}"} - taskTemplate := dummyContainerTaskTemplate(command, args) - taskCtx := dummyContainerTaskContext(taskTemplate, containerResourceRequirements, nil) + testCases := []struct { + name string + taskTemplate *core.TaskTemplate + taskMetadata pluginsCore.TaskExecutionMetadata + expectServiceAccount string + }{ + { + name: "BuildResource", + taskTemplate: dummyContainerTaskTemplate(command, args), + taskMetadata: dummyContainerTaskMetadata(containerResourceRequirements, nil, true), + expectServiceAccount: serviceAccount, + }, + { + name: "BuildResource_PodTemplate", + taskTemplate: dummyContainerTaskTemplateWithPodSpec(command, args), + taskMetadata: dummyContainerTaskMetadata(containerResourceRequirements, nil, true), + expectServiceAccount: podTemplateServiceAccount, + }, + { + name: "BuildResource_SecurityContext", + taskTemplate: dummyContainerTaskTemplate(command, args), + taskMetadata: dummyContainerTaskMetadata(containerResourceRequirements, nil, false), + expectServiceAccount: securityContextServiceAccount, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + taskCtx := dummyContainerTaskContext(tc.taskTemplate, tc.taskMetadata) - r, err := DefaultPodPlugin.BuildResource(context.TODO(), taskCtx) - assert.NoError(t, err) - assert.NotNil(t, r) - j, ok := r.(*v1.Pod) - assert.True(t, ok) + r, err := DefaultPodPlugin.BuildResource(context.TODO(), taskCtx) + assert.NoError(t, err) + assert.NotNil(t, r) + j, ok := r.(*v1.Pod) + assert.True(t, ok) - assert.NotEmpty(t, j.Spec.Containers) - assert.Equal(t, containerResourceRequirements.Limits[v1.ResourceCPU], j.Spec.Containers[0].Resources.Limits[v1.ResourceCPU]) + assert.NotEmpty(t, j.Spec.Containers) + assert.Equal(t, containerResourceRequirements.Limits[v1.ResourceCPU], j.Spec.Containers[0].Resources.Limits[v1.ResourceCPU]) - // TODO: Once configurable, test when setting storage is supported on the cluster vs not. - storageRes := j.Spec.Containers[0].Resources.Limits[v1.ResourceStorage] - assert.Equal(t, int64(0), (&storageRes).Value()) + // TODO: Once configurable, test when setting storage is supported on the cluster vs not. + storageRes := j.Spec.Containers[0].Resources.Limits[v1.ResourceStorage] + assert.Equal(t, int64(0), (&storageRes).Value()) - assert.Equal(t, command, j.Spec.Containers[0].Command) - assert.Equal(t, []string{"test-data-reference"}, j.Spec.Containers[0].Args) + assert.Equal(t, command, j.Spec.Containers[0].Command) + assert.Equal(t, []string{"test-data-reference"}, j.Spec.Containers[0].Args) - assert.Equal(t, "service-account", j.Spec.ServiceAccountName) + assert.Equal(t, tc.expectServiceAccount, j.Spec.ServiceAccountName) + }) + } } func TestContainerTaskExecutor_BuildResource_ExtendedResources(t *testing.T) { @@ -252,7 +323,8 @@ func TestContainerTaskExecutor_BuildResource_ExtendedResources(t *testing.T) { t.Run(f.name, func(t *testing.T) { taskTemplate := dummyContainerTaskTemplate([]string{"command"}, []string{"{{.Input}}"}) taskTemplate.ExtendedResources = f.extendedResourcesBase - taskContext := dummyContainerTaskContext(taskTemplate, f.resources, f.extendedResourcesOverride) + taskMetadata := dummyContainerTaskMetadata(f.resources, f.extendedResourcesOverride, true) + taskContext := dummyContainerTaskContext(taskTemplate, taskMetadata) r, err := DefaultPodPlugin.BuildResource(context.TODO(), taskContext) assert.Nil(t, err) assert.NotNil(t, r) @@ -277,7 +349,8 @@ func TestContainerTaskExecutor_GetTaskStatus(t *testing.T) { command := []string{"command"} args := []string{"{{.Input}}"} taskTemplate := dummyContainerTaskTemplate(command, args) - taskCtx := dummyContainerTaskContext(taskTemplate, containerResourceRequirements, nil) + taskMetadata := dummyContainerTaskMetadata(containerResourceRequirements, nil, true) + taskCtx := dummyContainerTaskContext(taskTemplate, taskMetadata) j := &v1.Pod{ Status: v1.PodStatus{}, @@ -366,7 +439,8 @@ func TestContainerTaskExecutor_GetTaskStatus_InvalidImageName(t *testing.T) { command := []string{"command"} args := []string{"{{.Input}}"} taskTemplate := dummyContainerTaskTemplate(command, args) - taskCtx := dummyContainerTaskContext(taskTemplate, containerResourceRequirements, nil) + taskMetadata := dummyContainerTaskMetadata(containerResourceRequirements, nil, true) + taskCtx := dummyContainerTaskContext(taskTemplate, taskMetadata) ctx := context.TODO() reason := "InvalidImageName" diff --git a/flyteplugins/go/tasks/plugins/k8s/pod/plugin.go b/flyteplugins/go/tasks/plugins/k8s/pod/plugin.go index 11de877021..b266a6f5e8 100644 --- a/flyteplugins/go/tasks/plugins/k8s/pod/plugin.go +++ b/flyteplugins/go/tasks/plugins/k8s/pod/plugin.go @@ -126,7 +126,9 @@ func (p plugin) BuildResource(ctx context.Context, taskCtx pluginsCore.TaskExecu objectMeta.Annotations[flytek8s.PrimaryContainerKey] = primaryContainerName } - podSpec.ServiceAccountName = flytek8s.GetServiceAccountNameFromTaskExecutionMetadata(taskCtx.TaskExecutionMetadata()) + if len(podSpec.ServiceAccountName) == 0 { + podSpec.ServiceAccountName = flytek8s.GetServiceAccountNameFromTaskExecutionMetadata(taskCtx.TaskExecutionMetadata()) + } pod := flytek8s.BuildIdentityPod() pod.ObjectMeta = *objectMeta From b9907f43568edcd3d248ad19d22b5643b0cf7285 Mon Sep 17 00:00:00 2001 From: Kevin Su Date: Wed, 6 Dec 2023 15:52:14 -0800 Subject: [PATCH 15/19] Fix flaky test_monitor (#4537) * Fix flaky test_monitor Signed-off-by: Kevin Su * fix test Signed-off-by: Kevin Su --------- Signed-off-by: Kevin Su Co-authored-by: Eduardo Apolinario <653394+eapolinario@users.noreply.github.com> --- .../go/tasks/pluginmachinery/internal/webapi/monitor_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flyteplugins/go/tasks/pluginmachinery/internal/webapi/monitor_test.go b/flyteplugins/go/tasks/pluginmachinery/internal/webapi/monitor_test.go index c47d77ae76..1628582156 100644 --- a/flyteplugins/go/tasks/pluginmachinery/internal/webapi/monitor_test.go +++ b/flyteplugins/go/tasks/pluginmachinery/internal/webapi/monitor_test.go @@ -21,6 +21,7 @@ import ( func Test_monitor(t *testing.T) { ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) tCtx := &mocks.TaskExecutionContext{} ctxMeta := &mocks.TaskExecutionMetadata{} execID := &mocks.TaskExecutionID{} @@ -70,6 +71,7 @@ func Test_monitor(t *testing.T) { // Wait for sync to run to actually delete the resource wg.Wait() + cancel() cachedItem, err = cacheObj.GetOrCreate("generated_name", CacheItem{Resource: "new_resource"}) assert.NoError(t, err) assert.Equal(t, "new_resource", cachedItem.(CacheItem).Resource.(string)) From f536d917f54fd9766aecf67964678ae95ae68eef Mon Sep 17 00:00:00 2001 From: Flyte Bot Date: Thu, 7 Dec 2023 03:32:46 -0800 Subject: [PATCH 16/19] Update boilerplate version (#4541) Signed-off-by: Flyte-Bot Co-authored-by: flyte-bot --- boilerplate/flyte/end2end/run-tests.py | 94 +++---------------- .../flyte/golang_test_targets/Makefile | 7 +- .../golang_test_targets/download_tooling.sh | 1 + .../flyte/golang_test_targets/goimports | 1 + 4 files changed, 17 insertions(+), 86 deletions(-) diff --git a/boilerplate/flyte/end2end/run-tests.py b/boilerplate/flyte/end2end/run-tests.py index 9f8a8e85cb..905f29079c 100644 --- a/boilerplate/flyte/end2end/run-tests.py +++ b/boilerplate/flyte/end2end/run-tests.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 - -import datetime import json import sys import time import traceback -from typing import Dict, List, Mapping, Tuple, Optional +from typing import Dict, List, Optional import click import requests @@ -17,79 +15,6 @@ WAIT_TIME = 10 MAX_ATTEMPTS = 200 -# This dictionary maps the names found in the flytesnacks manifest to a list of workflow names and -# inputs. This is so we can progressively cover all priorities in the original flytesnacks manifest, -# starting with "core". -FLYTESNACKS_WORKFLOW_GROUPS: Mapping[str, List[Tuple[str, dict]]] = { - "lite": [ - ("basics.hello_world.hello_world_wf", {}), - ], - "core": [ - # ("development_lifecycle.decks.image_renderer_wf", {}), - # The chain_workflows example in flytesnacks expects to be running in a sandbox. - ("advanced_composition.chain_entities.chain_workflows_wf", {}), - ("advanced_composition.dynamics.wf", {"s1": "Pear", "s2": "Earth"}), - ("advanced_composition.map_task.my_map_workflow", {"a": [1, 2, 3, 4, 5]}), - # Workflows that use nested executions cannot be launched via flyteremote. - # This issue is being tracked in https://github.com/flyteorg/flyte/issues/1482. - # ("control_flow.run_conditions.multiplier", {"my_input": 0.5}), - # ("control_flow.run_conditions.multiplier_2", {"my_input": 10}), - # ("control_flow.run_conditions.multiplier_3", {"my_input": 5}), - # ("control_flow.run_conditions.basic_boolean_wf", {"seed": 5}), - # ("control_flow.run_conditions.bool_input_wf", {"b": True}), - # ("control_flow.run_conditions.nested_conditions", {"my_input": 0.4}), - # ("control_flow.run_conditions.consume_outputs", {"my_input": 0.4, "seed": 7}), - # ("control_flow.run_merge_sort.merge_sort", {"numbers": [5, 4, 3, 2, 1], "count": 5}), - ("advanced_composition.subworkflows.parent_workflow", {"my_input1": "hello"}), - ("advanced_composition.subworkflows.nested_parent_wf", {"a": 3}), - ("basics.workflow.simple_wf", {"x": [1, 2, 3], "y": [1, 2, 3]}), - # TODO: enable new files and folders workflows - # ("basics.files.rotate_one_workflow", {"in_image": "https://upload.wikimedia.org/wikipedia/commons/d/d2/Julia_set_%28C_%3D_0.285%2C_0.01%29.jpg"}), - # ("basics.folders.download_and_rotate", {}), - ("basics.hello_world.hello_world_wf", {}), - ("basics.named_outputs.simple_wf_with_named_outputs", {}), - # # Getting a 403 for the wikipedia image - # # ("basics.reference_task.wf", {}), - ("data_types_and_io.dataclass.dataclass_wf", {"x": 10, "y": 20}), - # Enums are not supported in flyteremote - # ("type_system.enums.enum_wf", {"c": "red"}), - ("data_types_and_io.structured_dataset.simple_sd_wf", {"a": 42}), - # ("my.imperative.workflow.example", {"in1": "hello", "in2": "foo"}), - ], - "integrations-k8s-spark": [ - ( - "k8s_spark_plugin.pyspark_pi.my_spark", - {"triggered_date": datetime.datetime.now()}, - ), - ], - "integrations-kfpytorch": [ - ("kfpytorch_plugin.pytorch_mnist.pytorch_training_wf", {}), - ], - "integrations-kftensorflow": [ - ("kftensorflow_plugin.tf_mnist.mnist_tensorflow_workflow", {}), - ], - # "integrations-pod": [ - # ("pod.pod.pod_workflow", {}), - # ], - "integrations-pandera_examples": [ - ("pandera_plugin.basic_schema_example.process_data", {}), - # TODO: investigate type mismatch float -> numpy.float64 - # ("pandera_plugin.validating_and_testing_ml_pipelines.pipeline", {"data_random_state": 42, "model_random_state": 99}), - ], - "integrations-modin_examples": [ - ("modin_plugin.knn_classifier.pipeline", {}), - ], - "integrations-papermilltasks": [ - ("papermill_plugin.simple.nb_to_python_wf", {"f": 3.1415926535}), - ], - "integrations-greatexpectations": [ - ("greatexpectations_plugin.task_example.simple_wf", {}), - ("greatexpectations_plugin.task_example.file_wf", {}), - ("greatexpectations_plugin.task_example.schema_wf", {}), - ("greatexpectations_plugin.task_example.runtime_wf", {}), - ], -} - def execute_workflow( remote: FlyteRemote, @@ -137,6 +62,7 @@ def schedule_workflow_groups( workflow_groups: List[str], remote: FlyteRemote, terminate_workflow_on_failure: bool, + parsed_manifest: List[dict], cluster_pool_name: Optional[str] = None, ) -> Dict[str, bool]: """ @@ -146,7 +72,12 @@ def schedule_workflow_groups( executions_by_wfgroup = {} # Schedule executions for each workflow group, for wf_group in workflow_groups: - workflows = FLYTESNACKS_WORKFLOW_GROUPS.get(wf_group, []) + workflow_group_item = list( + filter(lambda item: item["name"] == wf_group, parsed_manifest) + ) + workflows = [] + if workflow_group_item: + workflows = workflow_group_item[0]["examples"] executions_by_wfgroup[wf_group] = [ execute_workflow(remote, tag, workflow[0], workflow[1], cluster_pool_name) for workflow in workflows @@ -188,12 +119,12 @@ def schedule_workflow_groups( return results -def valid(workflow_group): +def valid(workflow_group, parsed_manifest): """ - Return True if a workflow group is contained in FLYTESNACKS_WORKFLOW_GROUPS, + Return True if a workflow group is contained in parsed_manifest, False otherwise. """ - return workflow_group in FLYTESNACKS_WORKFLOW_GROUPS.keys() + return workflow_group in set(wf_group["name"] for wf_group in parsed_manifest) def run( @@ -233,7 +164,7 @@ def run( results = [] valid_workgroups = [] for workflow_group in workflow_groups: - if not valid(workflow_group): + if not valid(workflow_group, parsed_manifest): results.append( { "label": workflow_group, @@ -249,6 +180,7 @@ def run( valid_workgroups, remote, terminate_workflow_on_failure, + parsed_manifest, cluster_pool_name, ) diff --git a/boilerplate/flyte/golang_test_targets/Makefile b/boilerplate/flyte/golang_test_targets/Makefile index d3ab9817f7..280e1e55e4 100644 --- a/boilerplate/flyte/golang_test_targets/Makefile +++ b/boilerplate/flyte/golang_test_targets/Makefile @@ -3,9 +3,6 @@ # # TO OPT OUT OF UPDATES, SEE https://github.com/flyteorg/boilerplate/blob/master/Readme.rst -.PHONY: codespell -codespell: - git ls-files | grep -vE 'go\.mod|go\.sum|flyteidl/|\.pb$$|\.git|\.pdf|\.svg|requirements\.txt|gen/' | xargs codespell -w .PHONY: download_tooling download_tooling: #download dependencies (including test deps) for the package @@ -16,8 +13,8 @@ generate: download_tooling #generate go code @boilerplate/flyte/golang_test_targets/go-gen.sh .PHONY: lint -lint: codespell download_tooling #lints the package for common code smells - GL_DEBUG=linters_output,env golangci-lint run --fix --deadline=5m --exclude deprecated -v +lint: download_tooling #lints the package for common code smells + GL_DEBUG=linters_output,env golangci-lint run --deadline=5m --exclude deprecated -v # If code is failing goimports linter, this will fix. # skips 'vendor' diff --git a/boilerplate/flyte/golang_test_targets/download_tooling.sh b/boilerplate/flyte/golang_test_targets/download_tooling.sh index c7e5577ef3..9cd49959f4 100755 --- a/boilerplate/flyte/golang_test_targets/download_tooling.sh +++ b/boilerplate/flyte/golang_test_targets/download_tooling.sh @@ -19,6 +19,7 @@ tools=( "github.com/EngHabu/mockery/cmd/mockery" "github.com/flyteorg/flytestdlib/cli/pflags@latest" "github.com/golangci/golangci-lint/cmd/golangci-lint" + "github.com/daixiang0/gci" "github.com/alvaroloes/enumer" "github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc" ) diff --git a/boilerplate/flyte/golang_test_targets/goimports b/boilerplate/flyte/golang_test_targets/goimports index af1829036c..40f50d106e 100755 --- a/boilerplate/flyte/golang_test_targets/goimports +++ b/boilerplate/flyte/golang_test_targets/goimports @@ -6,3 +6,4 @@ # TO OPT OUT OF UPDATES, SEE https://github.com/flyteorg/boilerplate/blob/master/Readme.rst goimports -w $(find . -type f -name '*.go' -not -path "./vendor/*" -not -path "./pkg/client/*" -not -path "./boilerplate/*") +gci write -s standard -s default -s "prefix(github.com/flyteorg)" --custom-order --skip-generated . From c6a765332aaf7d7bf2ffc1a6d85aaae6f4ec3068 Mon Sep 17 00:00:00 2001 From: Samhita Alla Date: Thu, 7 Dec 2023 17:27:29 +0530 Subject: [PATCH 17/19] remove hardcoded list of tests (#4521) * remove hardcoded list of tests Signed-off-by: Samhita Alla * latest version Signed-off-by: Samhita Alla * latest version Signed-off-by: Samhita Alla * add sensor Signed-off-by: Samhita Alla * add flytesnacks to the path Signed-off-by: Samhita Alla * add flytesnacks to the path Signed-off-by: Samhita Alla --------- Signed-off-by: Samhita Alla Co-authored-by: Eduardo Apolinario <653394+eapolinario@users.noreply.github.com> --- .github/workflows/end2end.yml | 15 +++------------ .github/workflows/single-binary.yml | 23 +++++++---------------- docs/integrations.md | 6 ++---- 3 files changed, 12 insertions(+), 32 deletions(-) diff --git a/.github/workflows/end2end.yml b/.github/workflows/end2end.yml index cee310b195..aff4665fee 100644 --- a/.github/workflows/end2end.yml +++ b/.github/workflows/end2end.yml @@ -79,16 +79,7 @@ jobs: - name: Register P0 tests if: ${{ inputs.priorities == 'P0' }} run: | - for f in \ - basics/basics/hello_world.py \ - basics/basics/workflow.py \ - basics/basics/named_outputs.py \ - advanced_composition/advanced_composition/chain_entities.py \ - advanced_composition/advanced_composition/dynamics.py \ - advanced_composition/advanced_composition/map_task.py \ - advanced_composition/advanced_composition/subworkflows.py \ - data_types_and_io/data_types_and_io/dataclass.py \ - data_types_and_io/data_types_and_io/structured_dataset.py ; + while read -r line; do pyflyte --config ./boilerplate/flyte/end2end/functional-test-config.yaml \ register \ @@ -96,8 +87,8 @@ jobs: --domain development \ --image cr.flyte.org/flyteorg/flytekit:py3.11-latest \ --version ${{ env.FLYTESNACKS_VERSION }} \ - flytesnacks/examples/$f; - done + flytesnacks/$line; + done < flytesnacks/flyte_tests.txt - name: Register all flytesnacks examples if: ${{ inputs.priorities != 'P0' }} uses: unionai/flyte-register-action@v0.0.2 diff --git a/.github/workflows/single-binary.yml b/.github/workflows/single-binary.yml index 630068da00..5a22cf4594 100644 --- a/.github/workflows/single-binary.yml +++ b/.github/workflows/single-binary.yml @@ -27,7 +27,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '1.19' + go-version: "1.19" - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: @@ -129,8 +129,8 @@ jobs: sandbox-bundled-functional-tests: runs-on: ubuntu-latest env: - FLYTESNACKS_PRIORITIES: 'P0' - FLYTESNACKS_VERSION: '' + FLYTESNACKS_PRIORITIES: "P0" + FLYTESNACKS_VERSION: "" timeout-minutes: 20 needs: [build-and-push-single-binary-image] steps: @@ -164,7 +164,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: '3.11' + python-version: "3.11" - uses: unionai/flytectl-setup-action@v0.0.1 - name: Setup sandbox run: | @@ -193,16 +193,7 @@ jobs: # ref: ${{ env.FLYTESNACKS_VERSION }} - name: Register specific tests run: | - for f in \ - basics/basics/hello_world.py \ - basics/basics/workflow.py \ - basics/basics/named_outputs.py \ - advanced_composition/advanced_composition/chain_entities.py \ - advanced_composition/advanced_composition/dynamics.py \ - advanced_composition/advanced_composition/map_task.py \ - advanced_composition/advanced_composition/subworkflows.py \ - data_types_and_io/data_types_and_io/dataclass.py \ - data_types_and_io/data_types_and_io/structured_dataset.py ; + while read -r line; do pyflyte --config ./boilerplate/flyte/end2end/functional-test-config.yaml \ register \ @@ -210,8 +201,8 @@ jobs: --domain development \ --image cr.flyte.org/flyteorg/flytekit:py3.11-latest \ --version ${{ env.FLYTESNACKS_VERSION }} \ - flytesnacks/examples/$f; - done + flytesnacks/$line; + done < flytesnacks/flyte_tests.txt - name: End2End run: | make end2end_execute diff --git a/docs/integrations.md b/docs/integrations.md index 34ebfd073d..5a4bbcc909 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -49,13 +49,12 @@ Data is automatically marshalled and unmarshalled in and out of the plugin. User {py:class}`~flytekit.core.base_task.PythonTask` API defined in Flytekit. Flytekit Plugins are lazily loaded and can be released independently like libraries. We follow a convention to name the -plugin like `flytekitplugins-*`, where * indicates the package to be integrated into Flytekit. For example +plugin like `flytekitplugins-*`, where \* indicates the package to be integrated into Flytekit. For example `flytekitplugins-papermill` enables users to author Flytekit tasks using [Papermill](https://papermill.readthedocs.io/en/latest/). You can find the plugins maintained by the core Flyte team [here](https://github.com/flyteorg/flytekit/tree/master/plugins). ::: - ## Native Backend Plugins Native Backend Plugins are the plugins that can be executed without any external service dependencies because the compute is @@ -83,7 +82,6 @@ orchestrated by Flyte itself, within its provisioned Kubernetes clusters. (external_service_backend_plugins)= - ## External Service Backend Plugins As the term suggests, external service backend plugins relies on external services like @@ -138,7 +136,6 @@ Flyte uses Kustomize to generate the the deployment configuration which can be l :::: - ## Custom Container Tasks Because Flyte uses executable docker containers as the smallest unit of compute, you can write custom tasks with the @@ -208,6 +205,7 @@ flytesnacks/examples/athena_plugin/index flytesnacks/examples/aws_batch_plugin/index flytesnacks/examples/hive_plugin/index flytesnacks/examples/mmcloud_plugin/index +flytesnacks/examples/sensor/index flytesnacks/examples/snowflake_plugin/index flytesnacks/examples/databricks_plugin/index flytesnacks/examples/bigquery_plugin/index From e221f9fc909b55c11a3e089745eea5059fd46689 Mon Sep 17 00:00:00 2001 From: Niels Bantilan Date: Fri, 8 Dec 2023 13:20:38 -0500 Subject: [PATCH 18/19] manually create flytekit/_version.py file in docs build (#4556) Signed-off-by: Niels Bantilan --- docs/_ext/import_projects.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/_ext/import_projects.py b/docs/_ext/import_projects.py index b4cb011012..8962c40855 100644 --- a/docs/_ext/import_projects.py +++ b/docs/_ext/import_projects.py @@ -33,6 +33,11 @@ class Project: def update_sys_path_for_flytekit(import_project_config: ImportProjectsConfig): + # create flytekit/_version.py file manually + with open(f"{import_project_config.flytekit_api_dir}/flytekit/_version.py", "w") as f: + f.write(f'__version__ = "dev"') + + # add flytekit to python path flytekit_dir = os.path.abspath(import_project_config.flytekit_api_dir) flytekit_src_dir = os.path.abspath(os.path.join(flytekit_dir, "flytekit")) From f4402788cd2ae58eddd2bcfc72b29afd9d498fcd Mon Sep 17 00:00:00 2001 From: Niels Bantilan Date: Fri, 8 Dec 2023 16:20:02 -0500 Subject: [PATCH 19/19] introduce conda-lock file for docs (#4553) * introduce conda-lock file for docs Signed-off-by: Niels Bantilan * add back _version.py Signed-off-by: Niels Bantilan --------- Signed-off-by: Niels Bantilan --- .github/workflows/codespell.yml | 2 +- .github/workflows/tests.yml | 15 +- Makefile | 8 + docs/.readthedocs.yaml | 11 +- monodocs-environment.lock.yaml | 16701 ++++++++++++++++++++++++++++++ monodocs-environment.yaml | 5 + 6 files changed, 16732 insertions(+), 10 deletions(-) create mode 100644 monodocs-environment.lock.yaml diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index b56407b54d..c90557d62d 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -25,4 +25,4 @@ jobs: - name: Codespell uses: codespell-project/actions-codespell@v2 with: - skip: "*.pb" + skip: "*.pb,monodocs-environment.lock.yaml" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a04cd49a50..4d1d46d645 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,14 +31,15 @@ jobs: uses: actions/checkout@v4 - uses: conda-incubator/setup-miniconda@v3 with: + auto-update-conda: true python-version: 3.9 - mamba-version: "*" - channels: conda-forge - channel-priority: true - activate-environment: monodocs-env - environment-file: monodocs-environment.yaml - shell: bash -el {0} run: | + conda install -c conda-forge conda-lock + conda-lock install -n monodocs-env monodocs-environment.lock.yaml + - shell: bash -el {0} + run: | + conda activate monodocs-env conda info conda list conda config --show-sources @@ -48,7 +49,9 @@ jobs: uses: ts-graphviz/setup-graphviz@v1 - name: Build the documentation shell: bash -el {0} - run: make docs + run: | + conda activate monodocs-env + make docs generate_kustomize: runs-on: ubuntu-latest diff --git a/Makefile b/Makefile index 3400f627bb..ffc33ebe23 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,14 @@ install-piptools: ## Install pip-tools doc-requirements.txt: doc-requirements.in install-piptools $(call PIP_COMPILE,doc-requirements.in) +.PHONY: install-conda-lock +install-conda-lock: + pip install conda-lock + +.PHONY: conda-lock +conda-lock: install-conda-lock + conda-lock -f monodocs-environment.yaml --without-cuda --lockfile monodocs-environment.lock.yaml + .PHONY: stats stats: @generate-dashboard -o deployment/stats/prometheus/flytepropeller-dashboard.json stats/flytepropeller.dashboard.py diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml index 9e9f236bc3..a4dae7daf7 100644 --- a/docs/.readthedocs.yaml +++ b/docs/.readthedocs.yaml @@ -8,10 +8,15 @@ build: os: "ubuntu-22.04" tools: python: "mambaforge-22.9" + commands: + - cat monodocs-environment.lock.yaml + - mamba install -c conda-forge conda-lock + - conda-lock install -p /home/docs/monodocs-env monodocs-environment.lock.yaml + - conda info + - conda env list + - cat docs/conf.py + - cd docs && /home/docs/monodocs-env/bin/python -m sphinx -T -E -b html -d docs/_build/doctrees -D language=en . $READTHEDOCS_OUTPUT/html # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/conf.py - -conda: - environment: monodocs-environment.yaml diff --git a/monodocs-environment.lock.yaml b/monodocs-environment.lock.yaml new file mode 100644 index 0000000000..a38ac46199 --- /dev/null +++ b/monodocs-environment.lock.yaml @@ -0,0 +1,16701 @@ +# This lock file was generated by conda-lock (https://github.com/conda/conda-lock). DO NOT EDIT! +# +# A "lock file" contains a concrete list of package versions (with checksums) to be installed. Unlike +# e.g. `conda env create`, the resulting environment will not change as new package versions become +# available, unless you explicitly update the lock file. +# +# Install this environment as "YOURENV" with: +# conda-lock install -n YOURENV --file monodocs-environment.lock.yaml +# To update a single package to the latest version compatible with the version constraints in the source: +# conda-lock lock --lockfile monodocs-environment.lock.yaml --update PACKAGE +# To re-solve the entire environment, e.g. after changing a version constraint in the source file: +# conda-lock -f monodocs-environment.yaml --lockfile monodocs-environment.lock.yaml +version: 1 +metadata: + content_hash: + linux-64: 3a9f560148ced9e3d0ea648a9c75182aa28620f4b5d8a71e8738b68f5aa82d9c + osx-arm64: 3e3496c6bf2eb845154495bdc2437f35ffb436bcb39c93362e6f6d22b91aae90 + channels: + - url: conda-forge + used_env_vars: [] + platforms: + - linux-64 + - osx-arm64 + sources: + - monodocs-environment.yaml +package: +- name: _libgcc_mutex + version: '0.1' + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 + hash: + md5: d7c89558ba9fa0495403155b64376d81 + sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 + category: main + optional: false +- name: _openmp_mutex + version: '4.5' + manager: conda + platform: linux-64 + dependencies: + _libgcc_mutex: '0.1' + llvm-openmp: '>=9.0.1' + url: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_kmp_llvm.tar.bz2 + hash: + md5: 562b26ba2e19059551a811e72ab7f793 + sha256: 84a66275da3a66e3f3e70e9d8f10496d807d01a9e4ec16cd2274cc5e28c478fc + category: main + optional: false +- name: absl-py + version: 2.0.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/absl-py-2.0.0-pyhd8ed1ab_0.conda + hash: + md5: 2361c56617987bb6623dcbf8bab5cdc4 + sha256: 99e2a54d079d91909d6d12d2336d792fd2ab666620d2ac761cd09d0e552dd44d + category: main + optional: false +- name: absl-py + version: 2.0.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/absl-py-2.0.0-pyhd8ed1ab_0.conda + hash: + md5: 2361c56617987bb6623dcbf8bab5cdc4 + sha256: 99e2a54d079d91909d6d12d2336d792fd2ab666620d2ac761cd09d0e552dd44d + category: main + optional: false +- name: adal + version: 1.2.7 + manager: conda + platform: linux-64 + dependencies: + cryptography: '>=1.1.0' + pyjwt: '>=1.0.0' + python: '>=3.6' + python-dateutil: '>=2.1.0' + requests: '>=2.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/adal-1.2.7-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 1a0f134d22bad81e93f1e130b35afb35 + sha256: 3631c3713355d8fa81a77489dbc803b5004ea3be7e02b4ac9c16391f67dc57d5 + category: main + optional: false +- name: adal + version: 1.2.7 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + requests: '>=2.0.0' + pyjwt: '>=1.0.0' + cryptography: '>=1.1.0' + python-dateutil: '>=2.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/adal-1.2.7-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 1a0f134d22bad81e93f1e130b35afb35 + sha256: 3631c3713355d8fa81a77489dbc803b5004ea3be7e02b4ac9c16391f67dc57d5 + category: main + optional: false +- name: adlfs + version: 2023.10.0 + manager: conda + platform: linux-64 + dependencies: + aiohttp: '>=3.7.0' + azure-core: '>=1.23.1,<2.0' + azure-datalake-store: '>=0.0.46,<0.1' + azure-identity: '' + azure-storage-blob: '>=12.12.0' + fsspec: '>=2023.9.0' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/adlfs-2023.10.0-pyhd8ed1ab_0.conda + hash: + md5: 8549734dc1b3c3a8d99d7993fe35996c + sha256: a2df0742c398cbb586e30d4be1ea35ead6f36ca0b6b69dead48503a0424abb69 + category: main + optional: false +- name: adlfs + version: 2023.10.0 + manager: conda + platform: osx-arm64 + dependencies: + azure-identity: '' + python: '>=3.8' + azure-datalake-store: '>=0.0.46,<0.1' + aiohttp: '>=3.7.0' + azure-storage-blob: '>=12.12.0' + azure-core: '>=1.23.1,<2.0' + fsspec: '>=2023.9.0' + url: https://conda.anaconda.org/conda-forge/noarch/adlfs-2023.10.0-pyhd8ed1ab_0.conda + hash: + md5: 8549734dc1b3c3a8d99d7993fe35996c + sha256: a2df0742c398cbb586e30d4be1ea35ead6f36ca0b6b69dead48503a0424abb69 + category: main + optional: false +- name: aiobotocore + version: 2.8.0 + manager: conda + platform: linux-64 + dependencies: + aiohttp: '>=3.7.4.post0,<4.0.0' + aioitertools: '>=0.5.1,<1.0.0' + botocore: '>=1.32.4,<1.33.2' + python: '>=3.8' + wrapt: '>=1.10.10,<2.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/aiobotocore-2.8.0-pyhd8ed1ab_0.conda + hash: + md5: 877b0ea381ffddb7f98768b6851a2bba + sha256: a8ddcb54ba540f61f6a68b84db7c6e0a324c0dbe0ea95882ddc3f25253824977 + category: main + optional: false +- name: aiobotocore + version: 2.8.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + wrapt: '>=1.10.10,<2.0.0' + aioitertools: '>=0.5.1,<1.0.0' + aiohttp: '>=3.7.4.post0,<4.0.0' + botocore: '>=1.32.4,<1.33.2' + url: https://conda.anaconda.org/conda-forge/noarch/aiobotocore-2.8.0-pyhd8ed1ab_0.conda + hash: + md5: 877b0ea381ffddb7f98768b6851a2bba + sha256: a8ddcb54ba540f61f6a68b84db7c6e0a324c0dbe0ea95882ddc3f25253824977 + category: main + optional: false +- name: aiohttp + version: 3.9.1 + manager: conda + platform: linux-64 + dependencies: + aiosignal: '>=1.1.2' + async-timeout: '>=4.0,<5.0' + attrs: '>=17.3.0' + frozenlist: '>=1.1.1' + libgcc-ng: '>=12' + multidict: '>=4.5,<7.0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + yarl: '>=1.0,<2.0' + url: https://conda.anaconda.org/conda-forge/linux-64/aiohttp-3.9.1-py39hd1e30aa_0.conda + hash: + md5: c94f6e40db7d4828430ac0d8efe6a3d7 + sha256: 9ef3be4aed65d22f29a03a1bbc5b36ecab14b279efbe729241270831ff5f17b4 + category: main + optional: false +- name: aiohttp + version: 3.9.1 + manager: conda + platform: osx-arm64 + dependencies: + aiosignal: '>=1.1.2' + async-timeout: '>=4.0,<5.0' + attrs: '>=17.3.0' + frozenlist: '>=1.1.1' + multidict: '>=4.5,<7.0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + yarl: '>=1.0,<2.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aiohttp-3.9.1-py39h17cfd9d_0.conda + hash: + md5: f6fc543795790782846e7f69404293a1 + sha256: d43c95aa1a91ba65454ff246daca6697aaca17b674a179bd232c8e3360bb48c1 + category: main + optional: false +- name: aioitertools + version: 0.11.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + typing_extensions: '>=4.0' + url: https://conda.anaconda.org/conda-forge/noarch/aioitertools-0.11.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 59c40397276a286241c65faec5e1be3c + sha256: be2dbd6710438fa48b83bf06841091227276ae545d145dfe5cb5149c6484e951 + category: main + optional: false +- name: aioitertools + version: 0.11.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + typing_extensions: '>=4.0' + url: https://conda.anaconda.org/conda-forge/noarch/aioitertools-0.11.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 59c40397276a286241c65faec5e1be3c + sha256: be2dbd6710438fa48b83bf06841091227276ae545d145dfe5cb5149c6484e951 + category: main + optional: false +- name: aiosignal + version: 1.3.1 + manager: conda + platform: linux-64 + dependencies: + frozenlist: '>=1.1.0' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: d1e1eb7e21a9e2c74279d87dafb68156 + sha256: 575c742e14c86575986dc867463582a970463da50b77264cdf54df74f5563783 + category: main + optional: false +- name: aiosignal + version: 1.3.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + frozenlist: '>=1.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: d1e1eb7e21a9e2c74279d87dafb68156 + sha256: 575c742e14c86575986dc867463582a970463da50b77264cdf54df74f5563783 + category: main + optional: false +- name: alabaster + version: 0.7.13 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.13-pyhd8ed1ab_0.conda + hash: + md5: 06006184e203b61d3525f90de394471e + sha256: b2d160a050996950434c6e87a174fc01c4a937cbeffbdd20d1b46126b4478a95 + category: main + optional: false +- name: alabaster + version: 0.7.13 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.13-pyhd8ed1ab_0.conda + hash: + md5: 06006184e203b61d3525f90de394471e + sha256: b2d160a050996950434c6e87a174fc01c4a937cbeffbdd20d1b46126b4478a95 + category: main + optional: false +- name: alembic + version: 1.13.0 + manager: conda + platform: linux-64 + dependencies: + importlib-metadata: '' + importlib_resources: '' + mako: '' + python: '>=3.7' + sqlalchemy: '>=1.3.0' + typing-extensions: '>=4' + url: https://conda.anaconda.org/conda-forge/noarch/alembic-1.13.0-pyhd8ed1ab_0.conda + hash: + md5: 7f0372c1cfa41891787ddf267334c0c7 + sha256: d6dd010632bc5272fe7e51646651c5fb9ae9b7663113b94aa585d6bcb43834b0 + category: main + optional: false +- name: alembic + version: 1.13.0 + manager: conda + platform: osx-arm64 + dependencies: + importlib-metadata: '' + importlib_resources: '' + mako: '' + python: '>=3.7' + sqlalchemy: '>=1.3.0' + typing-extensions: '>=4' + url: https://conda.anaconda.org/conda-forge/noarch/alembic-1.13.0-pyhd8ed1ab_0.conda + hash: + md5: 7f0372c1cfa41891787ddf267334c0c7 + sha256: d6dd010632bc5272fe7e51646651c5fb9ae9b7663113b94aa585d6bcb43834b0 + category: main + optional: false +- name: altair + version: 4.2.2 + manager: conda + platform: linux-64 + dependencies: + entrypoints: '' + jinja2: '' + jsonschema: '>=3.0' + numpy: '>=0.18' + pandas: '>=0.18' + python: '>=3.7' + toolz: '' + url: https://conda.anaconda.org/conda-forge/noarch/altair-4.2.2-pyhd8ed1ab_0.conda + hash: + md5: afca9c6a93335c55bbc84072011e86dc + sha256: 5b36be4717e05b7c1f016d3534b7fe316381260ac2367a7815ff96fb88273deb + category: main + optional: false +- name: altair + version: 4.2.2 + manager: conda + platform: osx-arm64 + dependencies: + jinja2: '' + toolz: '' + entrypoints: '' + python: '>=3.7' + pandas: '>=0.18' + jsonschema: '>=3.0' + numpy: '>=0.18' + url: https://conda.anaconda.org/conda-forge/noarch/altair-4.2.2-pyhd8ed1ab_0.conda + hash: + md5: afca9c6a93335c55bbc84072011e86dc + sha256: 5b36be4717e05b7c1f016d3534b7fe316381260ac2367a7815ff96fb88273deb + category: main + optional: false +- name: ansiwrap + version: 0.8.4 + manager: conda + platform: linux-64 + dependencies: + python: <3.12.0a0 + textwrap3: '' + url: https://conda.anaconda.org/conda-forge/noarch/ansiwrap-0.8.4-py_0.tar.bz2 + hash: + md5: f09557e2a7cbd2470a2ab6353000cebd + sha256: 34e2445a78857c7418ab738b3a3c88f3226923676c3c185688dd570a6f9129a4 + category: main + optional: false +- name: ansiwrap + version: 0.8.4 + manager: conda + platform: osx-arm64 + dependencies: + textwrap3: '' + python: <3.12.0a0 + url: https://conda.anaconda.org/conda-forge/noarch/ansiwrap-0.8.4-py_0.tar.bz2 + hash: + md5: f09557e2a7cbd2470a2ab6353000cebd + sha256: 34e2445a78857c7418ab738b3a3c88f3226923676c3c185688dd570a6f9129a4 + category: main + optional: false +- name: anyio + version: 4.1.0 + manager: conda + platform: linux-64 + dependencies: + exceptiongroup: '>=1.0.2' + idna: '>=2.8' + python: '>=3.8' + sniffio: '>=1.1' + url: https://conda.anaconda.org/conda-forge/noarch/anyio-4.1.0-pyhd8ed1ab_0.conda + hash: + md5: 76a3b574717769c4c937c2afa2f1069f + sha256: d9d64b29d8a4f58a8d5f9cb0af80b70fd4e038a6e328b039899f7cd93863a82e + category: main + optional: false +- name: anyio + version: 4.1.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + sniffio: '>=1.1' + idna: '>=2.8' + exceptiongroup: '>=1.0.2' + url: https://conda.anaconda.org/conda-forge/noarch/anyio-4.1.0-pyhd8ed1ab_0.conda + hash: + md5: 76a3b574717769c4c937c2afa2f1069f + sha256: d9d64b29d8a4f58a8d5f9cb0af80b70fd4e038a6e328b039899f7cd93863a82e + category: main + optional: false +- name: aplus + version: 0.11.0 + manager: conda + platform: linux-64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/aplus-0.11.0-py_1.tar.bz2 + hash: + md5: 7785bb1ae3202fb550f23699c6f89121 + sha256: 7f2734233106b9ccfcf0bcd916cfdd39b59dcedf1a8832e6b1ec0048b6bc1ba2 + category: main + optional: false +- name: aplus + version: 0.11.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/aplus-0.11.0-py_1.tar.bz2 + hash: + md5: 7785bb1ae3202fb550f23699c6f89121 + sha256: 7f2734233106b9ccfcf0bcd916cfdd39b59dcedf1a8832e6b1ec0048b6bc1ba2 + category: main + optional: false +- name: appnope + version: 0.1.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.3-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 54ac328d703bff191256ffa1183126d1 + sha256: b209a68ac55eb9ecad7042f0d4eedef5da924699f6cdf54ac1826869cfdae742 + category: main + optional: false +- name: argon2-cffi + version: 23.1.0 + manager: conda + platform: linux-64 + dependencies: + argon2-cffi-bindings: '' + python: '>=3.7' + typing-extensions: '' + url: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-23.1.0-pyhd8ed1ab_0.conda + hash: + md5: 3afef1f55a1366b4d3b6a0d92e2235e4 + sha256: 130766446f5507bd44df957b6b5c898a8bd98f024bb426ed6cb9ff1ad67fc677 + category: main + optional: false +- name: argon2-cffi + version: 23.1.0 + manager: conda + platform: osx-arm64 + dependencies: + typing-extensions: '' + argon2-cffi-bindings: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-23.1.0-pyhd8ed1ab_0.conda + hash: + md5: 3afef1f55a1366b4d3b6a0d92e2235e4 + sha256: 130766446f5507bd44df957b6b5c898a8bd98f024bb426ed6cb9ff1ad67fc677 + category: main + optional: false +- name: argon2-cffi-bindings + version: 21.2.0 + manager: conda + platform: linux-64 + dependencies: + cffi: '>=1.0.1' + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-21.2.0-py39hd1e30aa_4.conda + hash: + md5: 6a04738e75f877b68552fc19cb045233 + sha256: 63c6f462a18e655e6c5fe4e433ac94100bca1a076e5bb5382c2479ac7a42fd54 + category: main + optional: false +- name: argon2-cffi-bindings + version: 21.2.0 + manager: conda + platform: osx-arm64 + dependencies: + cffi: '>=1.0.1' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-21.2.0-py39h0f82c59_4.conda + hash: + md5: d9a4812f8124406d841a869d55a96d50 + sha256: 6046a15172dcfa0d94d3e8fc7cc4d173db3e34fa8a49fb05f0de086c3569fae1 + category: main + optional: false +- name: arrow + version: 1.3.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + python-dateutil: '>=2.7.0' + types-python-dateutil: '>=2.8.10' + url: https://conda.anaconda.org/conda-forge/noarch/arrow-1.3.0-pyhd8ed1ab_0.conda + hash: + md5: b77d8c2313158e6e461ca0efb1c2c508 + sha256: ff49825c7f9e29e09afa6284300810e7a8640d621740efb47c4541f4dc4969db + category: main + optional: false +- name: arrow + version: 1.3.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + python-dateutil: '>=2.7.0' + types-python-dateutil: '>=2.8.10' + url: https://conda.anaconda.org/conda-forge/noarch/arrow-1.3.0-pyhd8ed1ab_0.conda + hash: + md5: b77d8c2313158e6e461ca0efb1c2c508 + sha256: ff49825c7f9e29e09afa6284300810e7a8640d621740efb47c4541f4dc4969db + category: main + optional: false +- name: asn1crypto + version: 1.5.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/asn1crypto-1.5.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: f3f2ab3ce28979a24d1a988ba211eb9b + sha256: 1354731d0eb1b406b66b3cb3d6ab74d7cbe9c0ec1d30b9e5afa366d4539e4687 + category: main + optional: false +- name: asn1crypto + version: 1.5.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/asn1crypto-1.5.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: f3f2ab3ce28979a24d1a988ba211eb9b + sha256: 1354731d0eb1b406b66b3cb3d6ab74d7cbe9c0ec1d30b9e5afa366d4539e4687 + category: main + optional: false +- name: astroid + version: 3.0.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + typing-extensions: '>=4.0.0' + url: https://conda.anaconda.org/conda-forge/linux-64/astroid-3.0.1-py39hf3d152e_0.conda + hash: + md5: 16a8c72dec1f429ed768680746f08780 + sha256: 819b5797715c4f771fc258dc0f9bb98540dcd812e6f92ed9753723e00624ae59 + category: main + optional: false +- name: astroid + version: 3.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + typing-extensions: '>=4.0.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/astroid-3.0.1-py39h2804cbe_0.conda + hash: + md5: fb91e1d11a7649304784ff28ce8eaf97 + sha256: cd14d172abbb9b30568557ad3b523ffcb6a75495cc6e161c14df25c1b023afbb + category: main + optional: false +- name: asttokens + version: 2.4.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + six: '>=1.12.0' + url: https://conda.anaconda.org/conda-forge/noarch/asttokens-2.4.1-pyhd8ed1ab_0.conda + hash: + md5: 5f25798dcefd8252ce5f9dc494d5f571 + sha256: 708168f026df19a0344983754d27d1f7b28bb21afc7b97a82f02c4798a3d2111 + category: main + optional: false +- name: asttokens + version: 2.4.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + six: '>=1.12.0' + url: https://conda.anaconda.org/conda-forge/noarch/asttokens-2.4.1-pyhd8ed1ab_0.conda + hash: + md5: 5f25798dcefd8252ce5f9dc494d5f571 + sha256: 708168f026df19a0344983754d27d1f7b28bb21afc7b97a82f02c4798a3d2111 + category: main + optional: false +- name: astunparse + version: 1.6.3 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + six: '>=1.6.1,<2.0' + url: https://conda.anaconda.org/conda-forge/noarch/astunparse-1.6.3-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 000b6f68a0bfaba800ced7500c11780f + sha256: e5173d1ed038038e24c0623f0219dc587ee8663cf7efa737e7075128edbc6c60 + category: main + optional: false +- name: astunparse + version: 1.6.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + six: '>=1.6.1,<2.0' + url: https://conda.anaconda.org/conda-forge/noarch/astunparse-1.6.3-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 000b6f68a0bfaba800ced7500c11780f + sha256: e5173d1ed038038e24c0623f0219dc587ee8663cf7efa737e7075128edbc6c60 + category: main + optional: false +- name: async-lru + version: 2.0.4 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + typing_extensions: '>=4.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.0.4-pyhd8ed1ab_0.conda + hash: + md5: 3d081de3a6ea9f894bbb585e8e3a4dcb + sha256: 7ed83731979fe5b046c157730e50af0e24454468bbba1ed8fc1a3107db5d7518 + category: main + optional: false +- name: async-lru + version: 2.0.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + typing_extensions: '>=4.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.0.4-pyhd8ed1ab_0.conda + hash: + md5: 3d081de3a6ea9f894bbb585e8e3a4dcb + sha256: 7ed83731979fe5b046c157730e50af0e24454468bbba1ed8fc1a3107db5d7518 + category: main + optional: false +- name: async-timeout + version: 4.0.3 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + typing-extensions: '>=3.6.5' + url: https://conda.anaconda.org/conda-forge/noarch/async-timeout-4.0.3-pyhd8ed1ab_0.conda + hash: + md5: 3ce482ec3066e6d809dbbb1d1679f215 + sha256: bd8b698e7f037a9c6107216646f1191f4f7a7fc6da6c34d1a6d4c211bcca8979 + category: main + optional: false +- name: async-timeout + version: 4.0.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + typing-extensions: '>=3.6.5' + url: https://conda.anaconda.org/conda-forge/noarch/async-timeout-4.0.3-pyhd8ed1ab_0.conda + hash: + md5: 3ce482ec3066e6d809dbbb1d1679f215 + sha256: bd8b698e7f037a9c6107216646f1191f4f7a7fc6da6c34d1a6d4c211bcca8979 + category: main + optional: false +- name: atk-1.0 + version: 2.38.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libglib: '>=2.74.1,<3.0a0' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-hd4edc92_1.tar.bz2 + hash: + md5: 6c72ec3e660a51736913ef6ea68c454b + sha256: 2f9314de13c1f0b54510a2afa0cdc02c0e3f828fccfc4277734f9590b11a65f1 + category: main + optional: false +- name: atk-1.0 + version: 2.38.0 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=14.0.4' + libglib: '>=2.74.1,<3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hcb7b3dd_1.tar.bz2 + hash: + md5: 3c98bfeed7717a9cf5af18c295f49f3a + sha256: d40f103467fd2fa426072691919fd135a4fed4a2b03cd12256ff0fee37a98249 + category: main + optional: false +- name: attrs + version: 23.1.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/attrs-23.1.0-pyh71513ae_1.conda + hash: + md5: 3edfead7cedd1ab4400a6c588f3e75f8 + sha256: 063639cd568f5c7a557b0fb1cc27f098598c0d8ff869088bfeb82934674f8821 + category: main + optional: false +- name: attrs + version: 23.1.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/attrs-23.1.0-pyh71513ae_1.conda + hash: + md5: 3edfead7cedd1ab4400a6c588f3e75f8 + sha256: 063639cd568f5c7a557b0fb1cc27f098598c0d8ff869088bfeb82934674f8821 + category: main + optional: false +- name: aws-c-auth + version: 0.7.3 + manager: conda + platform: linux-64 + dependencies: + aws-c-cal: '>=0.6.1,<0.6.2.0a0' + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-http: '>=0.7.11,<0.7.12.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + aws-c-sdkutils: '>=0.1.12,<0.1.13.0a0' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.3-h28f7589_1.conda + hash: + md5: 97503d3e565004697f1651753aa95b9e + sha256: d811d310ea601fc37f8a843e8aa7992c3286702d163472bd80bd81c7cb301f7b + category: main + optional: false +- name: aws-c-auth + version: 0.7.3 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-cal: '>=0.6.1,<0.6.2.0a0' + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-http: '>=0.7.11,<0.7.12.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + aws-c-sdkutils: '>=0.1.12,<0.1.13.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-auth-0.7.3-h109ad1a_1.conda + hash: + md5: 55852033dc22d5a2c00d58583447d051 + sha256: 547c24057cb8459186aa09cbc97c58eeca7c9e44d227a01457a2261e1954a36a + category: main + optional: false +- name: aws-c-cal + version: 0.6.1 + manager: conda + platform: linux-64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + libgcc-ng: '>=12' + openssl: '>=3.1.2,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.1-hc309b26_1.conda + hash: + md5: cc09293a2c2b7fd77aff284f370c12c0 + sha256: e5de0a103e6eb6597c012d67daa5d8ccb65e25e1fe22ef5cb758835276be90b9 + category: main + optional: false +- name: aws-c-cal + version: 0.6.1 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + openssl: '>=3.1.2,<4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-cal-0.6.1-hb406d48_1.conda + hash: + md5: 2461f9de775b064f549d8e1c2e74c682 + sha256: 066a1933fe8c0c8c0e8a7dc11bada019813b1c09ab290cbaf904bddcd11e036d + category: main + optional: false +- name: aws-c-common + version: 0.9.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.9.0-hd590300_0.conda + hash: + md5: 71b89db63b5b504e7afc8ad901172e1e + sha256: d70c478150d2551bf7b200bfa3d7cb8a016471819a58bb7fe18a4e526dae3567 + category: main + optional: false +- name: aws-c-common + version: 0.9.0 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-common-0.9.0-hb547adb_0.conda + hash: + md5: 7d7f91d3daa8d7bbf1da8c97038e336f + sha256: ec15d841f362e6a4468e06117d985f7f6007568ba832416ff146d239b2f7f0c0 + category: main + optional: false +- name: aws-c-compression + version: 0.2.17 + manager: conda + platform: linux-64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h4d4d85c_2.conda + hash: + md5: 9ca99452635fe03eb5fa937f5ae604b0 + sha256: 8ff6538db97a861be404f11dbc01abe7d4bc9978df3e573af1d08e2590eb500e + category: main + optional: false +- name: aws-c-compression + version: 0.2.17 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-compression-0.2.17-he70778a_2.conda + hash: + md5: d7a30e85a98d14dcd2d0ca8ae8ca4372 + sha256: 0e5a93b88d77405af89586f4b776f68a3cfd1c9ed44da57ac2a6b042dc96a26c + category: main + optional: false +- name: aws-c-event-stream + version: 0.3.1 + manager: conda + platform: linux-64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + aws-checksums: '>=0.1.17,<0.1.18.0a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.3.1-h2e3709c_4.conda + hash: + md5: 2cf21b1cbc1c096a28ffa2892257a2c1 + sha256: e733a19296044d23f785f4c1c18f82efce1b032e0913af93e70dcce10de6f688 + category: main + optional: false +- name: aws-c-event-stream + version: 0.3.1 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + aws-checksums: '>=0.1.17,<0.1.18.0a0' + libcxx: '>=15.0.7' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-event-stream-0.3.1-hcf14f3f_4.conda + hash: + md5: e8196ecb071eb3c07067008403182323 + sha256: eb127382b09a721a916ebf54c7aef8acbeefd00d5e2b14c45ec69f847bb50bf1 + category: main + optional: false +- name: aws-c-http + version: 0.7.11 + manager: conda + platform: linux-64 + dependencies: + aws-c-cal: '>=0.6.1,<0.6.2.0a0' + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-compression: '>=0.2.17,<0.2.18.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.7.11-h00aa349_4.conda + hash: + md5: cb932dff7328ff620ce8059c9968b095 + sha256: a4a90f366fe9235be7700306efef999d2d95ebc53e3701efb899ff59eadae6cd + category: main + optional: false +- name: aws-c-http + version: 0.7.11 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-cal: '>=0.6.1,<0.6.2.0a0' + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-compression: '>=0.2.17,<0.2.18.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-http-0.7.11-hcbec455_4.conda + hash: + md5: 13a5f11f32954de3c6ee5680700ce421 + sha256: de3b7d7729acbe9883ce8b4ab28130042b9c2e39616b616ee57555522afed65d + category: main + optional: false +- name: aws-c-io + version: 0.13.32 + manager: conda + platform: linux-64 + dependencies: + aws-c-cal: '>=0.6.1,<0.6.2.0a0' + aws-c-common: '>=0.9.0,<0.9.1.0a0' + libgcc-ng: '>=12' + s2n: '>=1.3.49,<1.3.50.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.13.32-he9a53bd_1.conda + hash: + md5: 8a24e5820f4a0ffd2ed9c4722cd5d7ca + sha256: 14911a1d4b66b5b031129d173fd34cedf852e3698eddd1972cf57974ce280f49 + category: main + optional: false +- name: aws-c-io + version: 0.13.32 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-cal: '>=0.6.1,<0.6.2.0a0' + aws-c-common: '>=0.9.0,<0.9.1.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-io-0.13.32-he8ad1d2_1.conda + hash: + md5: f7b3961185b3476c4c5a2a5cd9ab0523 + sha256: 621cc2c5d73e245c002a7c6ede7b7f74dfdcaf7dc52f3284f339b2c09df41acf + category: main + optional: false +- name: aws-c-mqtt + version: 0.9.3 + manager: conda + platform: linux-64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-http: '>=0.7.11,<0.7.12.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.9.3-hb447be9_1.conda + hash: + md5: c520669eb0be9269a5f0d8ef62531882 + sha256: e804a788e6147f4466bd2a24b7d9c327bffbe98bfb7420ddeae47dae41b140d6 + category: main + optional: false +- name: aws-c-mqtt + version: 0.9.3 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-http: '>=0.7.11,<0.7.12.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-mqtt-0.9.3-hf45dd20_1.conda + hash: + md5: 2602feff0c3c7904cc9f743d5c5bdb74 + sha256: 1b0e3ac3b683f00f37e6caac12f3a3e257ded1c5f8e3f7cd59bdfb7068a5abee + category: main + optional: false +- name: aws-c-s3 + version: 0.3.14 + manager: conda + platform: linux-64 + dependencies: + aws-c-auth: '>=0.7.3,<0.7.4.0a0' + aws-c-cal: '>=0.6.1,<0.6.2.0a0' + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-http: '>=0.7.11,<0.7.12.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + aws-checksums: '>=0.1.17,<0.1.18.0a0' + libgcc-ng: '>=12' + openssl: '>=3.1.2,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.14-hf3aad02_1.conda + hash: + md5: a968ffa7e9fe0c257628033d393e512f + sha256: f986c222f1f22e9e8d4869846a975595f1d0043794b41a5cf30ac53b0e4f4852 + category: main + optional: false +- name: aws-c-s3 + version: 0.3.14 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-auth: '>=0.7.3,<0.7.4.0a0' + aws-c-cal: '>=0.6.1,<0.6.2.0a0' + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-http: '>=0.7.11,<0.7.12.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + aws-checksums: '>=0.1.17,<0.1.18.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-s3-0.3.14-hf0e1321_1.conda + hash: + md5: 01eb867a0851892b41cb57a7ecaeee8b + sha256: 02b7cd21bf1db9284d5e26cf9fb5a7f8a3e0a856ada807eb51d60e1d66cd8e78 + category: main + optional: false +- name: aws-c-sdkutils + version: 0.1.12 + manager: conda + platform: linux-64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.12-h4d4d85c_1.conda + hash: + md5: eba092fc6de212a01de0065f38fe8bbb + sha256: eb092d65be4e42301a0babcfccd44dbd086eadd6b84f7929c7e07c7449748280 + category: main + optional: false +- name: aws-c-sdkutils + version: 0.1.12 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-sdkutils-0.1.12-he70778a_1.conda + hash: + md5: a90a6413bbf361584033773c19cecb65 + sha256: 60bf0d3e7bd7bb368bbbc03f917b2a97198642ce8ed491f80c5cacbb6498c566 + category: main + optional: false +- name: aws-checksums + version: 0.1.17 + manager: conda + platform: linux-64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.17-h4d4d85c_1.conda + hash: + md5: 30f9df85ce23cd14faa9a4dfa50cca2b + sha256: df2356cf1cac39d9b872026275527718dac1d39f6e88fa5b0b56d06f6b90eb98 + category: main + optional: false +- name: aws-checksums + version: 0.1.17 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-checksums-0.1.17-he70778a_1.conda + hash: + md5: 5892420ce138d63e1f6e08c9915f0308 + sha256: 52606dcecd60ccc587d3c8f100cc30b7a8101f655e8d9b26a90dac9996030f52 + category: main + optional: false +- name: aws-crt-cpp + version: 0.21.0 + manager: conda + platform: linux-64 + dependencies: + aws-c-auth: '>=0.7.3,<0.7.4.0a0' + aws-c-cal: '>=0.6.1,<0.6.2.0a0' + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-event-stream: '>=0.3.1,<0.3.2.0a0' + aws-c-http: '>=0.7.11,<0.7.12.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + aws-c-mqtt: '>=0.9.3,<0.9.4.0a0' + aws-c-s3: '>=0.3.14,<0.3.15.0a0' + aws-c-sdkutils: '>=0.1.12,<0.1.13.0a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.21.0-hb942446_5.conda + hash: + md5: 07d92ed5403ad7b5c66ffd7d5b8f7e57 + sha256: 7456d3f9c3069be9c1faf82cd37885c270d0ee945bb5adb4cc3223c9439ccc7e + category: main + optional: false +- name: aws-crt-cpp + version: 0.21.0 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-auth: '>=0.7.3,<0.7.4.0a0' + aws-c-cal: '>=0.6.1,<0.6.2.0a0' + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-event-stream: '>=0.3.1,<0.3.2.0a0' + aws-c-http: '>=0.7.11,<0.7.12.0a0' + aws-c-io: '>=0.13.32,<0.13.33.0a0' + aws-c-mqtt: '>=0.9.3,<0.9.4.0a0' + aws-c-s3: '>=0.3.14,<0.3.15.0a0' + aws-c-sdkutils: '>=0.1.12,<0.1.13.0a0' + libcxx: '>=15.0.7' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-crt-cpp-0.21.0-hda227cd_5.conda + hash: + md5: dd47301eea0a420faa1546f5c5d708ff + sha256: 861bb8ca04a5cad23dfd444967e29735b2430350c7789dc5e869a4e71dac82ae + category: main + optional: false +- name: aws-sdk-cpp + version: 1.10.57 + manager: conda + platform: linux-64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-event-stream: '>=0.3.1,<0.3.2.0a0' + aws-crt-cpp: '>=0.21.0,<0.21.1.0a0' + libcurl: '>=8.2.1,<9.0a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.2,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-h85b1a90_19.conda + hash: + md5: 0605d3d60857fc07bd6a11e878fe0f08 + sha256: 2f44eaea9d88203f400229c3247575dd8ea7c20907cc6ea2e2d859f43c395141 + category: main + optional: false +- name: aws-sdk-cpp + version: 1.10.57 + manager: conda + platform: osx-arm64 + dependencies: + aws-c-common: '>=0.9.0,<0.9.1.0a0' + aws-c-event-stream: '>=0.3.1,<0.3.2.0a0' + aws-crt-cpp: '>=0.21.0,<0.21.1.0a0' + libcurl: '>=8.2.1,<9.0a0' + libcxx: '>=15.0.7' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.2,<4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-sdk-cpp-1.10.57-h1190f42_19.conda + hash: + md5: bd16f7f2a92c33d1767592c45588dbc7 + sha256: b176a2cf86d8c6891f5d234b2be4503492b37554241bad183b4524988c2e82e9 + category: main + optional: false +- name: azure-core + version: 1.29.5 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + requests: '>=2.18.4' + six: '>=1.11.0' + typing-extensions: '>=4.0.1' + url: https://conda.anaconda.org/conda-forge/noarch/azure-core-1.29.5-pyhd8ed1ab_0.conda + hash: + md5: 6e97f7d5387626f896515442002ac920 + sha256: 3f3ec0617e825bcabb70722ace9153dfdc02895aebb2179fc20b82eb30f79ec8 + category: main + optional: false +- name: azure-core + version: 1.29.5 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + requests: '>=2.18.4' + six: '>=1.11.0' + typing-extensions: '>=4.0.1' + url: https://conda.anaconda.org/conda-forge/noarch/azure-core-1.29.5-pyhd8ed1ab_0.conda + hash: + md5: 6e97f7d5387626f896515442002ac920 + sha256: 3f3ec0617e825bcabb70722ace9153dfdc02895aebb2179fc20b82eb30f79ec8 + category: main + optional: false +- name: azure-datalake-store + version: 0.0.51 + manager: conda + platform: linux-64 + dependencies: + adal: '>=0.4.2' + cffi: '' + python: '' + requests: '>=2.20.0' + url: https://conda.anaconda.org/conda-forge/noarch/azure-datalake-store-0.0.51-pyh9f0ad1d_0.tar.bz2 + hash: + md5: 0a6d240a3a8198dce8508a5409b4737e + sha256: 8ba71f78851d238d8dc9f469f88b2f5619c7f6f5d009a96bcbd8bd595ed85273 + category: main + optional: false +- name: azure-datalake-store + version: 0.0.51 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + cffi: '' + requests: '>=2.20.0' + adal: '>=0.4.2' + url: https://conda.anaconda.org/conda-forge/noarch/azure-datalake-store-0.0.51-pyh9f0ad1d_0.tar.bz2 + hash: + md5: 0a6d240a3a8198dce8508a5409b4737e + sha256: 8ba71f78851d238d8dc9f469f88b2f5619c7f6f5d009a96bcbd8bd595ed85273 + category: main + optional: false +- name: azure-identity + version: 1.15.0 + manager: conda + platform: linux-64 + dependencies: + azure-core: <2.0.0,>=1.23.0 + cryptography: '>=2.5' + msal: <2.0.0,>=1.24.0 + msal_extensions: <2.0.0,>=0.3.0 + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/azure-identity-1.15.0-pyhd8ed1ab_0.conda + hash: + md5: d1ef208ae2a355e5bb9cdce337644ce9 + sha256: a7a80ce603b0b2af0670e676b0ce96cc3fddd7c59f8f2c4d5767f5cfda7a74e9 + category: main + optional: false +- name: azure-identity + version: 1.15.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + cryptography: '>=2.5' + azure-core: <2.0.0,>=1.23.0 + msal_extensions: <2.0.0,>=0.3.0 + msal: <2.0.0,>=1.24.0 + url: https://conda.anaconda.org/conda-forge/noarch/azure-identity-1.15.0-pyhd8ed1ab_0.conda + hash: + md5: d1ef208ae2a355e5bb9cdce337644ce9 + sha256: a7a80ce603b0b2af0670e676b0ce96cc3fddd7c59f8f2c4d5767f5cfda7a74e9 + category: main + optional: false +- name: azure-storage-blob + version: 12.19.0 + manager: conda + platform: linux-64 + dependencies: + azure-core: <2.0.0,>=1.28.0 + cryptography: '>=2.1.4' + isodate: '>=0.6.1' + python: '>=3.7' + typing-extensions: '>=4.3.0' + url: https://conda.anaconda.org/conda-forge/noarch/azure-storage-blob-12.19.0-pyhd8ed1ab_0.conda + hash: + md5: a3ea5120c342b4c956022340ace5c0f8 + sha256: 385c2a82fd5183d2cc791747f63d81e8bda11e068ee0e29e945fe7cdfe20a817 + category: main + optional: false +- name: azure-storage-blob + version: 12.19.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + cryptography: '>=2.1.4' + typing-extensions: '>=4.3.0' + isodate: '>=0.6.1' + azure-core: <2.0.0,>=1.28.0 + url: https://conda.anaconda.org/conda-forge/noarch/azure-storage-blob-12.19.0-pyhd8ed1ab_0.conda + hash: + md5: a3ea5120c342b4c956022340ace5c0f8 + sha256: 385c2a82fd5183d2cc791747f63d81e8bda11e068ee0e29e945fe7cdfe20a817 + category: main + optional: false +- name: babel + version: 2.13.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + pytz: '' + setuptools: '' + url: https://conda.anaconda.org/conda-forge/noarch/babel-2.13.1-pyhd8ed1ab_0.conda + hash: + md5: 3ccff479c246692468f604df9c85ef26 + sha256: 1f955c700db16f65b16c9e9c1613436480d5497970b8030b7a9ebe1620cc2147 + category: main + optional: false +- name: babel + version: 2.13.1 + manager: conda + platform: osx-arm64 + dependencies: + setuptools: '' + pytz: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/babel-2.13.1-pyhd8ed1ab_0.conda + hash: + md5: 3ccff479c246692468f604df9c85ef26 + sha256: 1f955c700db16f65b16c9e9c1613436480d5497970b8030b7a9ebe1620cc2147 + category: main + optional: false +- name: bcrypt + version: 4.1.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-4.1.1-py39h9fdd4d6_0.conda + hash: + md5: be773757df1f0a5f7c783d6c56666ee7 + sha256: 6c1ea83b3a9f7d7ae5681cbd2eb6d4cc770e103c86f303ab3c568a7249383561 + category: main + optional: false +- name: bcrypt + version: 4.1.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-4.1.1-py39h8fec3ad_0.conda + hash: + md5: f301395d8fc233bd7427b18ab3200d6b + sha256: 474737d340938ac1ca74a2cef8648ae4632ceb3da98ef69dca894657aea94292 + category: main + optional: false +- name: beautifulsoup4 + version: 4.12.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + soupsieve: '>=1.2' + url: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.12.2-pyha770c72_0.conda + hash: + md5: a362ff7d976217f8fa78c0f1c4f59717 + sha256: 52d3e6bcd442537e22699cd227d8fdcfd54b708eeb8ee5b4c671a6a9b9cd74da + category: main + optional: false +- name: beautifulsoup4 + version: 4.12.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + soupsieve: '>=1.2' + url: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.12.2-pyha770c72_0.conda + hash: + md5: a362ff7d976217f8fa78c0f1c4f59717 + sha256: 52d3e6bcd442537e22699cd227d8fdcfd54b708eeb8ee5b4c671a6a9b9cd74da + category: main + optional: false +- name: binaryornot + version: 0.4.4 + manager: conda + platform: linux-64 + dependencies: + chardet: '' + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/binaryornot-0.4.4-py_1.tar.bz2 + hash: + md5: a556fa60840fcb9dd739d186bfd252f7 + sha256: 8f65c16a9f85285e1f704a26d4c5ced25f46544f5cc20dc8a4aebd7796f8011a + category: main + optional: false +- name: binaryornot + version: 0.4.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + chardet: '' + url: https://conda.anaconda.org/conda-forge/noarch/binaryornot-0.4.4-py_1.tar.bz2 + hash: + md5: a556fa60840fcb9dd739d186bfd252f7 + sha256: 8f65c16a9f85285e1f704a26d4c5ced25f46544f5cc20dc8a4aebd7796f8011a + category: main + optional: false +- name: black + version: 23.11.0 + manager: conda + platform: linux-64 + dependencies: + click: '>=8.0.0' + mypy_extensions: '>=0.4.3' + packaging: '>=22.0' + pathspec: '>=0.9' + platformdirs: '>=2' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + tomli: '>=1.1.0' + typing_extensions: '>=4.0.1' + url: https://conda.anaconda.org/conda-forge/linux-64/black-23.11.0-py39hf3d152e_0.conda + hash: + md5: 6b828d6f788dcbad32d4e2b8f89cb47c + sha256: 825751ba565514bb9c729e690f08119f3831f5cd0678afcace5c3a2a9d3a6a8c + category: main + optional: false +- name: black + version: 23.11.0 + manager: conda + platform: osx-arm64 + dependencies: + click: '>=8.0.0' + mypy_extensions: '>=0.4.3' + packaging: '>=22.0' + pathspec: '>=0.9' + platformdirs: '>=2' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + tomli: '>=1.1.0' + typing_extensions: '>=4.0.1' + url: https://conda.anaconda.org/conda-forge/osx-arm64/black-23.11.0-py39h2804cbe_0.conda + hash: + md5: 94746897e02fb5be3aafc99ae9862c56 + sha256: 62603be057db836bdee1b39ffc27a7c0be6b97dee5801b88d72cee00b55443d9 + category: main + optional: false +- name: blake3 + version: 0.3.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + numpy: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/blake3-0.3.3-py39h9fdd4d6_2.conda + hash: + md5: cb2f0e7c51a8b55641034e52be530714 + sha256: 7a5db684002e9e01c7387ba19a1e7954d9ef9f91656d3cd9f4cdf5250f0a1d5c + category: main + optional: false +- name: blake3 + version: 0.3.3 + manager: conda + platform: osx-arm64 + dependencies: + numpy: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/blake3-0.3.3-py39haff01fd_2.conda + hash: + md5: 60a7eeaab3b813d7e4cdce6bade7105f + sha256: ddd23c3c89bc54f66909cdfadced6b64799ff58b356f5f8d5f3295aa1da26d2e + category: main + optional: false +- name: bleach + version: 6.1.0 + manager: conda + platform: linux-64 + dependencies: + packaging: '' + python: '>=3.6' + setuptools: '' + six: '>=1.9.0' + webencodings: '' + url: https://conda.anaconda.org/conda-forge/noarch/bleach-6.1.0-pyhd8ed1ab_0.conda + hash: + md5: 0ed9d7c0e9afa7c025807a9a8136ea3e + sha256: 845e77ef495376c5c3c328ccfd746ca0ef1978150cae8eae61a300fe7755fb08 + category: main + optional: false +- name: bleach + version: 6.1.0 + manager: conda + platform: osx-arm64 + dependencies: + setuptools: '' + packaging: '' + webencodings: '' + python: '>=3.6' + six: '>=1.9.0' + url: https://conda.anaconda.org/conda-forge/noarch/bleach-6.1.0-pyhd8ed1ab_0.conda + hash: + md5: 0ed9d7c0e9afa7c025807a9a8136ea3e + sha256: 845e77ef495376c5c3c328ccfd746ca0ef1978150cae8eae61a300fe7755fb08 + category: main + optional: false +- name: blinker + version: 1.7.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/blinker-1.7.0-pyhd8ed1ab_0.conda + hash: + md5: 550da20b2c2e38be9cc44bb819fda5d5 + sha256: c8d72c2af4f57898dfd5e4c62ae67f7fea1490a37c8b6855460a170d61591177 + category: main + optional: false +- name: blinker + version: 1.7.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/blinker-1.7.0-pyhd8ed1ab_0.conda + hash: + md5: 550da20b2c2e38be9cc44bb819fda5d5 + sha256: c8d72c2af4f57898dfd5e4c62ae67f7fea1490a37c8b6855460a170d61591177 + category: main + optional: false +- name: blosc + version: 1.21.5 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + lz4-c: '>=1.9.3,<1.10.0a0' + snappy: '>=1.1.10,<2.0a0' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.5-h0f2a231_0.conda + hash: + md5: 009521b7ed97cca25f8f997f9e745976 + sha256: e2b15b017775d1bda8edbb1bc48e545e45364edefa4d926732fc5488cc600731 + category: main + optional: false +- name: bokeh + version: 3.3.2 + manager: conda + platform: linux-64 + dependencies: + contourpy: '>=1' + jinja2: '>=2.9' + numpy: '>=1.16' + packaging: '>=16.8' + pandas: '>=1.2' + pillow: '>=7.1.0' + python: '>=3.9' + pyyaml: '>=3.10' + tornado: '>=5.1' + xyzservices: '>=2021.09.1' + url: https://conda.anaconda.org/conda-forge/noarch/bokeh-3.3.2-pyhd8ed1ab_0.conda + hash: + md5: c02a7e79365121bd3bcc25f1b65f48a9 + sha256: 71c36a77422e58d66d1e1c126b09481ad05f7e80b1a86860496de566ed990e0e + category: main + optional: false +- name: bokeh + version: 2.4.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + pyyaml: '>=3.10' + tornado: '>=5.1' + typing_extensions: '>=3.10.0' + pillow: '>=7.1.0' + numpy: '>=1.11.3' + packaging: '>=16.8' + jinja2: '>=2.9' + url: https://conda.anaconda.org/conda-forge/noarch/bokeh-2.4.3-pyhd8ed1ab_3.tar.bz2 + hash: + md5: e4c6e6d99add99cede5328d811cacb21 + sha256: f37e33fb11ae76ff07ce726a3dbdf4cd26ffff1b52c126d2d2d136669d6b919f + category: main + optional: false +- name: botocore + version: 1.33.1 + manager: conda + platform: linux-64 + dependencies: + jmespath: '>=0.7.1,<2.0.0' + python: '>=3.7' + python-dateutil: '>=2.1,<3.0.0' + urllib3: '>=1.25.4,<1.27' + url: https://conda.anaconda.org/conda-forge/noarch/botocore-1.33.1-pyhd8ed1ab_0.conda + hash: + md5: b40066840291a0406bffe70e0334de62 + sha256: c9d214ae266f03797b3c06129b1a173593fc573affc09cfd02bba3bdd36c4827 + category: main + optional: false +- name: botocore + version: 1.33.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + python-dateutil: '>=2.1,<3.0.0' + jmespath: '>=0.7.1,<2.0.0' + urllib3: '>=1.25.4,<1.27' + url: https://conda.anaconda.org/conda-forge/noarch/botocore-1.33.1-pyhd8ed1ab_0.conda + hash: + md5: b40066840291a0406bffe70e0334de62 + sha256: c9d214ae266f03797b3c06129b1a173593fc573affc09cfd02bba3bdd36c4827 + category: main + optional: false +- name: branca + version: 0.7.0 + manager: conda + platform: linux-64 + dependencies: + jinja2: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/branca-0.7.0-pyhd8ed1ab_1.conda + hash: + md5: 980ae382aec2ebb7c20e8848f4d695d7 + sha256: 9013b381e6745a7f717b7f742d3fe366ba619f1670da0d849ae589c4e88b0dbc + category: main + optional: false +- name: brotli + version: 1.0.9 + manager: conda + platform: linux-64 + dependencies: + brotli-bin: 1.0.9 + libbrotlidec: 1.0.9 + libbrotlienc: 1.0.9 + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/brotli-1.0.9-h166bdaf_9.conda + hash: + md5: 4601544b4982ba1861fa9b9c607b2c06 + sha256: 2357d205931912def55df0dc53573361156b27856f9bf359d464da162812ec1f + category: main + optional: false +- name: brotli + version: 1.0.9 + manager: conda + platform: osx-arm64 + dependencies: + brotli-bin: 1.0.9 + libbrotlidec: 1.0.9 + libbrotlienc: 1.0.9 + url: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.0.9-h1a8c8d9_9.conda + hash: + md5: 856692dff5e450c269465e3256e1277b + sha256: 92c3062dd7e593a502c2f8d12e9ccca7ae1ef0363eb0b12faa47e1bb4fae42c7 + category: main + optional: false +- name: brotli-bin + version: 1.0.9 + manager: conda + platform: linux-64 + dependencies: + libbrotlidec: 1.0.9 + libbrotlienc: 1.0.9 + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.0.9-h166bdaf_9.conda + hash: + md5: d47dee1856d9cb955b8076eeff304a5b + sha256: 1c128f136a59ee2fa47d7fbd9b6fc8afa8460d340e4ae0e6f5419ebbd7539a10 + category: main + optional: false +- name: brotli-bin + version: 1.0.9 + manager: conda + platform: osx-arm64 + dependencies: + libbrotlidec: 1.0.9 + libbrotlienc: 1.0.9 + url: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.0.9-h1a8c8d9_9.conda + hash: + md5: 19ad562adca69541e67613022b41df5b + sha256: 4731892fb855f5993129515c5b63b36d049cc64e70611c6afa8f64aae5f51323 + category: main + optional: false +- name: brotli-python + version: 1.0.9 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.0.9-py39h5a03fae_9.conda + hash: + md5: d1601752c6f47af7bedf838be3d8ca6b + sha256: 18f296067e5f3f9fd9ea55ec89a0d91149455a5e5d1ddd26c53fb7fb2806dab0 + category: main + optional: false +- name: brotli-python + version: 1.0.9 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=14.0.6' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.0.9-py39h23fbdae_9.conda + hash: + md5: ef4c58e8f1811e0730accf3f425e2e5f + sha256: 217f4ef7481ee63935768668496426d16773b3933492c026ad2922a950a81c41 + category: main + optional: false +- name: bzip2 + version: 1.0.8 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda + hash: + md5: 69b8b6202a07720f448be700e300ccf4 + sha256: 242c0c324507ee172c0e0dd2045814e746bb303d1eb78870d182ceb0abc726a8 + category: main + optional: false +- name: bzip2 + version: 1.0.8 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h93a5062_5.conda + hash: + md5: 1bbc659ca658bfd49a481b5ef7a0f40f + sha256: bfa84296a638bea78a8bb29abc493ee95f2a0218775642474a840411b950fe5f + category: main + optional: false +- name: c-ares + version: 1.23.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.23.0-hd590300_0.conda + hash: + md5: d459949bc10f64dee1595c176c2e6291 + sha256: 6b0eee827bade11c2964a05867499a50ad2a9d1b14dfe18fb867a3bc9357f56f + category: main + optional: false +- name: c-ares + version: 1.23.0 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.23.0-h93a5062_0.conda + hash: + md5: b187f2b99e52905042d661f824666964 + sha256: de5385280dcad805428068adb1f4a7eb1e6ec8987e2f25c4ff5766e3fec3b4a2 + category: main + optional: false +- name: ca-certificates + version: 2023.11.17 + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2023.11.17-hbcca054_0.conda + hash: + md5: 01ffc8d36f9eba0ce0b3c1955fa780ee + sha256: fb4b9f4b7d885002db0b93e22f44b5b03791ef3d4efdc9d0662185a0faafd6b6 + category: main + optional: false +- name: ca-certificates + version: 2023.11.17 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2023.11.17-hf0a4a13_0.conda + hash: + md5: c01da7c77cfcba2107174e25c1d47384 + sha256: 75f4762a55f7e9453a603c967d549bfa0a7a9669d502d103cb6fbf8c86d993c6 + category: main + optional: false +- name: cached-property + version: 1.5.2 + manager: conda + platform: linux-64 + dependencies: + cached_property: '>=1.5.2,<1.5.3.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + hash: + md5: 9b347a7ec10940d3f7941ff6c460b551 + sha256: 561e6660f26c35d137ee150187d89767c988413c978e1b712d53f27ddf70ea17 + category: main + optional: false +- name: cached-property + version: 1.5.2 + manager: conda + platform: osx-arm64 + dependencies: + cached_property: '>=1.5.2,<1.5.3.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + hash: + md5: 9b347a7ec10940d3f7941ff6c460b551 + sha256: 561e6660f26c35d137ee150187d89767c988413c978e1b712d53f27ddf70ea17 + category: main + optional: false +- name: cached_property + version: 1.5.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + hash: + md5: 576d629e47797577ab0f1b351297ef4a + sha256: 6dbf7a5070cc43d90a1e4c2ec0c541c69d8e30a0e25f50ce9f6e4a432e42c5d7 + category: main + optional: false +- name: cached_property + version: 1.5.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + hash: + md5: 576d629e47797577ab0f1b351297ef4a + sha256: 6dbf7a5070cc43d90a1e4c2ec0c541c69d8e30a0e25f50ce9f6e4a432e42c5d7 + category: main + optional: false +- name: cachetools + version: 5.3.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/cachetools-5.3.2-pyhd8ed1ab_0.conda + hash: + md5: 185cc1bf1d5af90020292888a3c7eb5d + sha256: cb8a6688d5650e4546a5f3c5b825bfe3c82594f1f588a93817f1bdb23e74baad + category: main + optional: false +- name: cachetools + version: 4.2.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/cachetools-4.2.4-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 059a8732c1d81ffc93997cb8a236331f + sha256: c73709b168d12c802532706961dc8e54418b61cf99341fd6738bae060460c477 + category: main + optional: false +- name: cairo + version: 1.18.0 + manager: conda + platform: linux-64 + dependencies: + fontconfig: '>=2.14.2,<3.0a0' + fonts-conda-ecosystem: '' + freetype: '>=2.12.1,<3.0a0' + icu: '>=73.2,<74.0a0' + libgcc-ng: '>=12' + libglib: '>=2.78.0,<3.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libstdcxx-ng: '>=12' + libxcb: '>=1.15,<1.16.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + pixman: '>=0.42.2,<1.0a0' + xorg-libice: '>=1.1.1,<2.0a0' + xorg-libsm: '>=1.2.4,<2.0a0' + xorg-libx11: '>=1.8.6,<2.0a0' + xorg-libxext: '>=1.3.4,<2.0a0' + xorg-libxrender: '>=0.9.11,<0.10.0a0' + zlib: '' + url: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.0-h3faef2a_0.conda + hash: + md5: f907bb958910dc404647326ca80c263e + sha256: 142e2639a5bc0e99c44d76f4cc8dce9c6a2d87330c4beeabb128832cd871a86e + category: main + optional: false +- name: cairo + version: 1.18.0 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + fontconfig: '>=2.14.2,<3.0a0' + fonts-conda-ecosystem: '' + freetype: '>=2.12.1,<3.0a0' + icu: '>=73.2,<74.0a0' + libcxx: '>=16.0.6' + libglib: '>=2.78.0,<3.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + pixman: '>=0.42.2,<1.0a0' + zlib: '' + url: https://conda.anaconda.org/conda-forge/osx-arm64/cairo-1.18.0-hd1e100b_0.conda + hash: + md5: 3fa6eebabb77f65e82f86b72b95482db + sha256: 599f8820553b3a3405706d9cad390ac199e24515a0a82c87153c9b5b5fdba3b8 + category: main + optional: false +- name: certifi + version: 2023.11.17 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2023.11.17-pyhd8ed1ab_0.conda + hash: + md5: 2011bcf45376341dd1d690263fdbc789 + sha256: afa22b77128a812cb57bc707c297d926561bd225a3d9dd74205d87a3b2d14a96 + category: main + optional: false +- name: certifi + version: 2023.11.17 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2023.11.17-pyhd8ed1ab_0.conda + hash: + md5: 2011bcf45376341dd1d690263fdbc789 + sha256: afa22b77128a812cb57bc707c297d926561bd225a3d9dd74205d87a3b2d14a96 + category: main + optional: false +- name: cffi + version: 1.16.0 + manager: conda + platform: linux-64 + dependencies: + libffi: '>=3.4,<4.0a0' + libgcc-ng: '>=12' + pycparser: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.16.0-py39h7a31438_0.conda + hash: + md5: ac992767d7f8ed2cb27e71e78f0fb2d7 + sha256: 1536a2ca65caaf568bbdfe75aff8e12cb0e0507587b25af3b532a8bd22cb3ddb + category: main + optional: false +- name: cffi + version: 1.16.0 + manager: conda + platform: osx-arm64 + dependencies: + libffi: '>=3.4,<4.0a0' + pycparser: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-1.16.0-py39he153c15_0.conda + hash: + md5: 2be3a21503b84cbd74dd1c11f36c4a3c + sha256: 2766a3bec7747d14fe646b2a3ec4ba508495ea8b0a434213189d3e4d20e24e4b + category: main + optional: false +- name: cfgv + version: 3.3.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6.1' + url: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.3.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: ebb5f5f7dc4f1a3780ef7ea7738db08c + sha256: fbc03537a27ef756162c49b1d0608bf7ab12fa5e38ceb8563d6f4859e835ac5c + category: main + optional: false +- name: cfgv + version: 3.3.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6.1' + url: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.3.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: ebb5f5f7dc4f1a3780ef7ea7738db08c + sha256: fbc03537a27ef756162c49b1d0608bf7ab12fa5e38ceb8563d6f4859e835ac5c + category: main + optional: false +- name: cfitsio + version: 4.3.0 + manager: conda + platform: linux-64 + dependencies: + bzip2: '>=1.0.8,<2.0a0' + libcurl: '>=8.2.0,<9.0a0' + libgcc-ng: '>=12' + libgfortran-ng: '' + libgfortran5: '>=12.3.0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/cfitsio-4.3.0-hbdc6101_0.conda + hash: + md5: 797554b8b7603011e8677884381fbcc5 + sha256: c74938f1ade9b8f37b9fa8cc98a5b9262b325506f41d7492ad1d00146e0f1d08 + category: main + optional: false +- name: chardet + version: 5.2.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/chardet-5.2.0-py39hf3d152e_1.conda + hash: + md5: 514bcdeaf82679b99ac629cb6f2860f1 + sha256: 1733218d1da1ce2f1e9a0d28b6e9c62fe32c3b86c5bd7a0cdceb2f3a4b03cfa9 + category: main + optional: false +- name: chardet + version: 5.2.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/chardet-5.2.0-py39h2804cbe_1.conda + hash: + md5: 0e695a9b3912071c144c3d794b744432 + sha256: 0fa01ea9a2b31897af4ca95f3d6f92edd208e474ebd8d89ddfa9d05fe72477be + category: main + optional: false +- name: charset-normalizer + version: 3.3.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda + hash: + md5: 7f4a9e3fcff3f6356ae99244a014da6a + sha256: 20cae47d31fdd58d99c4d2e65fbdcefa0b0de0c84e455ba9d6356a4bdbc4b5b9 + category: main + optional: false +- name: charset-normalizer + version: 3.3.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda + hash: + md5: 7f4a9e3fcff3f6356ae99244a014da6a + sha256: 20cae47d31fdd58d99c4d2e65fbdcefa0b0de0c84e455ba9d6356a4bdbc4b5b9 + category: main + optional: false +- name: click + version: 8.1.7 + manager: conda + platform: linux-64 + dependencies: + __unix: '' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda + hash: + md5: f3ad426304898027fc619827ff428eca + sha256: f0016cbab6ac4138a429e28dbcb904a90305b34b3fe41a9b89d697c90401caec + category: main + optional: false +- name: click + version: 8.1.7 + manager: conda + platform: osx-arm64 + dependencies: + __unix: '' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda + hash: + md5: f3ad426304898027fc619827ff428eca + sha256: f0016cbab6ac4138a429e28dbcb904a90305b34b3fe41a9b89d697c90401caec + category: main + optional: false +- name: click-plugins + version: 1.1.1 + manager: conda + platform: linux-64 + dependencies: + click: '>=3.0' + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 + hash: + md5: 4fd2c6b53934bd7d96d1f3fdaf99b79f + sha256: ddef6e559dde6673ee504b0e29dd814d36e22b6b9b1f519fa856ee268905bf92 + category: main + optional: false +- name: cligj + version: 0.7.2 + manager: conda + platform: linux-64 + dependencies: + click: '>=4.0' + python: <4.0 + url: https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_1.tar.bz2 + hash: + md5: a29b7c141d6b2de4bb67788a5f107734 + sha256: 97bd58f0cfcff56a0bcda101e26f7d936625599325beba3e3a1fa512dd7fc174 + category: main + optional: false +- name: cloudpickle + version: 2.2.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/cloudpickle-2.2.1-pyhd8ed1ab_0.conda + hash: + md5: b325bfc4cff7d7f8a868f1f7ecc4ed16 + sha256: f0c2fd0e842899a05ddd7b147fb26424adf58be0e8e54e5bc68b8f7e67d05dcd + category: main + optional: false +- name: cloudpickle + version: 2.2.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/cloudpickle-2.2.1-pyhd8ed1ab_0.conda + hash: + md5: b325bfc4cff7d7f8a868f1f7ecc4ed16 + sha256: f0c2fd0e842899a05ddd7b147fb26424adf58be0e8e54e5bc68b8f7e67d05dcd + category: main + optional: false +- name: codespell + version: 2.2.6 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/codespell-2.2.6-pyhd8ed1ab_0.conda + hash: + md5: a206349b7bb7475ae580f987cb425bdd + sha256: b49d5482fbdeeb610275f6e7def3ee1409e6f2305b0eae4d37e23ada8b01e989 + category: main + optional: false +- name: codespell + version: 2.2.6 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/codespell-2.2.6-pyhd8ed1ab_0.conda + hash: + md5: a206349b7bb7475ae580f987cb425bdd + sha256: b49d5482fbdeeb610275f6e7def3ee1409e6f2305b0eae4d37e23ada8b01e989 + category: main + optional: false +- name: colorama + version: 0.4.6 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 3faab06a954c2a04039983f2c4a50d99 + sha256: 2c1b2e9755ce3102bca8d69e8f26e4f087ece73f50418186aee7c74bef8e1698 + category: main + optional: false +- name: colorama + version: 0.4.6 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 3faab06a954c2a04039983f2c4a50d99 + sha256: 2c1b2e9755ce3102bca8d69e8f26e4f087ece73f50418186aee7c74bef8e1698 + category: main + optional: false +- name: comm + version: 0.1.4 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + traitlets: '>=5.3' + url: https://conda.anaconda.org/conda-forge/noarch/comm-0.1.4-pyhd8ed1ab_0.conda + hash: + md5: c8eaca39e2b6abae1fc96acc929ae939 + sha256: 11057745946a95ee7cc4c98900a60c7362266a4cb28bc97d96cd88e3056eb701 + category: main + optional: false +- name: comm + version: 0.1.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + traitlets: '>=5.3' + url: https://conda.anaconda.org/conda-forge/noarch/comm-0.1.4-pyhd8ed1ab_0.conda + hash: + md5: c8eaca39e2b6abae1fc96acc929ae939 + sha256: 11057745946a95ee7cc4c98900a60c7362266a4cb28bc97d96cd88e3056eb701 + category: main + optional: false +- name: commonmark + version: 0.9.1 + manager: conda + platform: linux-64 + dependencies: + future: '>=0.14.0' + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/commonmark-0.9.1-py_0.tar.bz2 + hash: + md5: 6aa0173c14befcd577ded130cf6f22f5 + sha256: 10577f82bafd5d37f0c3f2122272d0dc1f2d133655c2bdd1a3cd5f910d0bd4c5 + category: main + optional: false +- name: commonmark + version: 0.9.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + future: '>=0.14.0' + url: https://conda.anaconda.org/conda-forge/noarch/commonmark-0.9.1-py_0.tar.bz2 + hash: + md5: 6aa0173c14befcd577ded130cf6f22f5 + sha256: 10577f82bafd5d37f0c3f2122272d0dc1f2d133655c2bdd1a3cd5f910d0bd4c5 + category: main + optional: false +- name: configparser + version: 5.3.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/configparser-5.3.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: c99fd5916160900dc5ff64204da99c4d + sha256: ce6ce9ee08437b46c284d52b076fb091cf6f2a9e12860d4a37546adbd5f53b28 + category: main + optional: false +- name: configparser + version: 5.3.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/configparser-5.3.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: c99fd5916160900dc5ff64204da99c4d + sha256: ce6ce9ee08437b46c284d52b076fb091cf6f2a9e12860d4a37546adbd5f53b28 + category: main + optional: false +- name: contourpy + version: 1.2.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + numpy: '>=1.20,<2' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.2.0-py39h7633fee_0.conda + hash: + md5: ed71ad3e30eb03da363fb797419cce98 + sha256: 7a85421667d97132c5d23575da63c2da850775c81832607e56bfd881c9750f3a + category: main + optional: false +- name: contourpy + version: 1.2.0 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + libcxx: '>=16.0.6' + numpy: '>=1.20,<2' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.2.0-py39he9de807_0.conda + hash: + md5: 1cf7d8ee627725a514622c863dd8821b + sha256: ac729314c46e04b455e0b1e08b2c223fe92c4f89e3e13c2ae42e1e349ad3958b + category: main + optional: false +- name: cookiecutter + version: 2.5.0 + manager: conda + platform: linux-64 + dependencies: + arrow: '' + binaryornot: '>=0.4.4' + click: '>=7.0,<9.0.0' + jinja2: '>=2.7,<4.0.0' + python: '>=3.7' + python-slugify: '>=4.0.0' + pyyaml: '>=5.3.1' + requests: '>=2.23.0' + rich: '' + url: https://conda.anaconda.org/conda-forge/noarch/cookiecutter-2.5.0-pyhca7485f_0.conda + hash: + md5: dd441f5f8ccf8d277ea2731b9523d341 + sha256: 7a58c9025e713e0227bfb9c8248cd40e116d84d17420e6ed23b916ee763230ee + category: main + optional: false +- name: cookiecutter + version: 2.5.0 + manager: conda + platform: osx-arm64 + dependencies: + rich: '' + arrow: '' + python: '>=3.7' + pyyaml: '>=5.3.1' + requests: '>=2.23.0' + python-slugify: '>=4.0.0' + binaryornot: '>=0.4.4' + jinja2: '>=2.7,<4.0.0' + click: '>=7.0,<9.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/cookiecutter-2.5.0-pyhca7485f_0.conda + hash: + md5: dd441f5f8ccf8d277ea2731b9523d341 + sha256: 7a58c9025e713e0227bfb9c8248cd40e116d84d17420e6ed23b916ee763230ee + category: main + optional: false +- name: croniter + version: 2.0.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + python-dateutil: '' + pytz: '>2021.1' + url: https://conda.anaconda.org/conda-forge/noarch/croniter-2.0.1-pyhd8ed1ab_0.conda + hash: + md5: f67f52c1f555785b86c3bd8e5de4c66f + sha256: 0a39004b6e4ddff1a323432c0790d61a8885f35af9e60cc7e76ad8f6d43e3f34 + category: main + optional: false +- name: croniter + version: 2.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python-dateutil: '' + python: '>=3.7' + pytz: '>2021.1' + url: https://conda.anaconda.org/conda-forge/noarch/croniter-2.0.1-pyhd8ed1ab_0.conda + hash: + md5: f67f52c1f555785b86c3bd8e5de4c66f + sha256: 0a39004b6e4ddff1a323432c0790d61a8885f35af9e60cc7e76ad8f6d43e3f34 + category: main + optional: false +- name: cryptography + version: 41.0.7 + manager: conda + platform: linux-64 + dependencies: + cffi: '>=1.12' + libgcc-ng: '>=12' + openssl: '>=3.1.4,<4.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/cryptography-41.0.7-py39he6105cc_1.conda + hash: + md5: c2503c6b2505714dd30d50717efe1826 + sha256: 704b189699c8eae0dff8b3d0886fb3ef5316b221676ee5d79d44575073bc9296 + category: main + optional: false +- name: cryptography + version: 41.0.7 + manager: conda + platform: osx-arm64 + dependencies: + cffi: '>=1.12' + openssl: '>=3.1.4,<4.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-41.0.7-py39hbc7c26c_1.conda + hash: + md5: 0511a9f0e97e23bf28fe345f92849237 + sha256: 291cf98d177a933b9ec6c35dc7630b181a73497c0fe9840e90c7a728716b5061 + category: main + optional: false +- name: cycler + version: 0.12.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda + hash: + md5: 5cd86562580f274031ede6aa6aa24441 + sha256: f221233f21b1d06971792d491445fd548224641af9443739b4b7b6d5d72954a8 + category: main + optional: false +- name: cycler + version: 0.12.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda + hash: + md5: 5cd86562580f274031ede6aa6aa24441 + sha256: f221233f21b1d06971792d491445fd548224641af9443739b4b7b6d5d72954a8 + category: main + optional: false +- name: cytoolz + version: 0.12.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + toolz: '>=0.10.0' + url: https://conda.anaconda.org/conda-forge/linux-64/cytoolz-0.12.2-py39hd1e30aa_1.conda + hash: + md5: e5b62f0c1f96413116f16d33973f1a44 + sha256: dc9b9ddb29d61463e8c5c5098b7f8d8a370d6d1a65830029000ff9c2299495e0 + category: main + optional: false +- name: cytoolz + version: 0.12.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + toolz: '>=0.10.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/cytoolz-0.12.2-py39h0f82c59_1.conda + hash: + md5: 55150781bf8d18e4df223e47abc4f1d7 + sha256: 4709ec855331b50230fbf09bec3fc833c744e2505e454c3513bdad18cbc0100c + category: main + optional: false +- name: dask + version: 2023.12.0 + manager: conda + platform: linux-64 + dependencies: + bokeh: '>=2.4.2,!=3.0.*' + cytoolz: '>=0.11.0' + dask-core: '>=2023.12.0,<2023.12.1.0a0' + distributed: '>=2023.12.0,<2023.12.1.0a0' + jinja2: '>=2.10.3' + lz4: '>=4.3.2' + numpy: '>=1.21' + pandas: '>=1.3' + pyarrow: '>=7.0' + pyarrow-hotfix: '' + python: '>=3.9' + url: https://conda.anaconda.org/conda-forge/noarch/dask-2023.12.0-pyhd8ed1ab_0.conda + hash: + md5: 5cfc00e93b71fba459bede86419d0f01 + sha256: c9725f37d8b05b2b1407ff00b17c9bcee39ed5a33f33f34d771e5bbf4762e737 + category: main + optional: false +- name: dask + version: 2023.2.0 + manager: conda + platform: osx-arm64 + dependencies: + jinja2: '' + lz4: '' + python: '>=3.8' + pandas: '>=1.0' + numpy: '>=1.18' + cytoolz: '>=0.8.2' + bokeh: '>=2.4.2,<3' + dask-core: '>=2023.2.0,<2023.2.1.0a0' + distributed: '>=2023.2.0,<2023.2.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/dask-2023.2.0-pyhd8ed1ab_0.conda + hash: + md5: c64c58bf99a686d8bdff8f9c4d33d615 + sha256: 8a0864a7ef94584f43be468d92f32a0f8a4ccab108b34168748c293847c51e67 + category: main + optional: false +- name: dask-core + version: 2023.12.0 + manager: conda + platform: linux-64 + dependencies: + click: '>=8.1' + cloudpickle: '>=1.5.0' + fsspec: '>=2021.09.0' + importlib_metadata: '>=4.13.0' + packaging: '>=20.0' + partd: '>=1.2.0' + python: '>=3.9' + pyyaml: '>=5.3.1' + toolz: '>=0.10.0' + url: https://conda.anaconda.org/conda-forge/noarch/dask-core-2023.12.0-pyhd8ed1ab_0.conda + hash: + md5: 95eae0785aed72998493140dc0115382 + sha256: e366163aa7325d14ca38ca72ca4672eeb4b7a7453573c47cfa90d0db60136b48 + category: main + optional: false +- name: dask-core + version: 2023.2.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + click: '>=7.0' + packaging: '>=20.0' + pyyaml: '>=5.3.1' + toolz: '>=0.8.2' + partd: '>=0.3.10' + fsspec: '>=0.6.0' + cloudpickle: '>=1.1.1' + url: https://conda.anaconda.org/conda-forge/noarch/dask-core-2023.2.0-pyhd8ed1ab_0.conda + hash: + md5: 156fb994a4e07091c4fad2c148589eb2 + sha256: a88c3d56f1d4657cbd6265184b95a0191bfec10e870aa3f1483eca1f46e35ddc + category: main + optional: false +- name: databricks-cli + version: 0.18.0 + manager: conda + platform: linux-64 + dependencies: + click: '>=7.0' + configparser: '>=0.3.5' + oauthlib: '>=3.1.0' + pyjwt: '>=1.7.0' + python: '>=3.7' + requests: '>=2.17.3' + six: '>=1.10.0' + tabulate: '>=0.7.7' + urllib3: '>=1.26.7,<3' + url: https://conda.anaconda.org/conda-forge/noarch/databricks-cli-0.18.0-pyhd8ed1ab_0.conda + hash: + md5: 5036bba5b1dd105148a5bab9ff4b0620 + sha256: 6ac45a54c2d7e14195d413bbe372f4636d00bc6ce76ffc0c737fb9c7d80a32eb + category: main + optional: false +- name: databricks-cli + version: 0.18.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + click: '>=7.0' + six: '>=1.10.0' + pyjwt: '>=1.7.0' + tabulate: '>=0.7.7' + requests: '>=2.17.3' + configparser: '>=0.3.5' + oauthlib: '>=3.1.0' + urllib3: '>=1.26.7,<3' + url: https://conda.anaconda.org/conda-forge/noarch/databricks-cli-0.18.0-pyhd8ed1ab_0.conda + hash: + md5: 5036bba5b1dd105148a5bab9ff4b0620 + sha256: 6ac45a54c2d7e14195d413bbe372f4636d00bc6ce76ffc0c737fb9c7d80a32eb + category: main + optional: false +- name: dataclasses-json + version: 0.5.7 + manager: conda + platform: linux-64 + dependencies: + marshmallow: '>=3.3.0,<4.0.0' + marshmallow-enum: '>=1.5.1,<2.0.0' + python: '>=3.6' + stringcase: 1.2.0,<2.0.0 + typing_inspect: '>=0.4.0' + url: https://conda.anaconda.org/conda-forge/noarch/dataclasses-json-0.5.7-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 460d0446b90718c6b535bfe807eab1cd + sha256: 8775cfe2a7583f724c1b424088f988eb480f242b9a09823e92f4af9df3c190de + category: main + optional: false +- name: dataclasses-json + version: 0.5.7 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + typing_inspect: '>=0.4.0' + marshmallow: '>=3.3.0,<4.0.0' + marshmallow-enum: '>=1.5.1,<2.0.0' + stringcase: 1.2.0,<2.0.0 + url: https://conda.anaconda.org/conda-forge/noarch/dataclasses-json-0.5.7-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 460d0446b90718c6b535bfe807eab1cd + sha256: 8775cfe2a7583f724c1b424088f988eb480f242b9a09823e92f4af9df3c190de + category: main + optional: false +- name: datasets + version: 2.14.7 + manager: conda + platform: linux-64 + dependencies: + aiohttp: '' + dill: '>=0.3.0,<0.3.8' + fsspec: '>=2023.1.0,<=2023.10.0' + huggingface_hub: '>=0.14.0,<1.0.0' + importlib-metadata: '' + multiprocess: '' + numpy: '>=1.17' + packaging: '' + pandas: '' + pyarrow: '>=8.0.0' + pyarrow-hotfix: '' + python: '>=3.8.0' + python-xxhash: '' + pyyaml: '>=5.1' + requests: '>=2.19.0' + tqdm: '>=4.62.1' + url: https://conda.anaconda.org/conda-forge/noarch/datasets-2.14.7-pyhd8ed1ab_0.conda + hash: + md5: 13675409f6e4c17d539adb0f2aecc335 + sha256: 6eba52c53088c7f8207ebb224393eea29a70bef1db28e2b794a7973d52284d23 + category: main + optional: false +- name: datasets + version: 2.14.7 + manager: conda + platform: osx-arm64 + dependencies: + pandas: '' + packaging: '' + importlib-metadata: '' + aiohttp: '' + python-xxhash: '' + multiprocess: '' + pyarrow-hotfix: '' + pyyaml: '>=5.1' + numpy: '>=1.17' + requests: '>=2.19.0' + pyarrow: '>=8.0.0' + python: '>=3.8.0' + tqdm: '>=4.62.1' + dill: '>=0.3.0,<0.3.8' + huggingface_hub: '>=0.14.0,<1.0.0' + fsspec: '>=2023.1.0,<=2023.10.0' + url: https://conda.anaconda.org/conda-forge/noarch/datasets-2.14.7-pyhd8ed1ab_0.conda + hash: + md5: 13675409f6e4c17d539adb0f2aecc335 + sha256: 6eba52c53088c7f8207ebb224393eea29a70bef1db28e2b794a7973d52284d23 + category: main + optional: false +- name: db-dtypes + version: 1.1.1 + manager: conda + platform: linux-64 + dependencies: + numpy: '>=1.16.6' + packaging: '>=17.0' + pandas: '>=0.24.2' + pyarrow: '>=3.0.0' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/db-dtypes-1.1.1-pyhd8ed1ab_0.conda + hash: + md5: 457a360baa01b5d8f2fcbe4c8f356633 + sha256: 565a01fc71a61d49f9599a9a3fc9ce67594e0256eab6e7529e5311c0d01c5429 + category: main + optional: false +- name: dbus + version: 1.13.6 + manager: conda + platform: linux-64 + dependencies: + expat: '>=2.4.2,<3.0a0' + libgcc-ng: '>=9.4.0' + libglib: '>=2.70.2,<3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2 + hash: + md5: ecfff944ba3960ecb334b9a2663d708d + sha256: 8f5f995699a2d9dbdd62c61385bfeeb57c82a681a7c8c5313c395aa0ccab68a5 + category: main + optional: false +- name: debugpy + version: 1.8.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.0-py39h3d6467e_1.conda + hash: + md5: 31e04f8c5eebb5306793482b5e0f8a78 + sha256: 804a293cdea90c8e95eb03ce2dfef14b0118c65fae9aff4326d8ce5e9a09bd7d + category: main + optional: false +- name: debugpy + version: 1.8.0 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.0-py39hb198ff7_1.conda + hash: + md5: 69119da204eec5434903d22a62618b5c + sha256: cf1d778e659e848b0016d62d6661fdea7fe36f321c42902490bb242baa130651 + category: main + optional: false +- name: decorator + version: 5.1.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/decorator-5.1.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 43afe5ab04e35e17ba28649471dd7364 + sha256: 328a6a379f9bdfd0230e51de291ce858e6479411ea4b0545fb377c71662ef3e2 + category: main + optional: false +- name: decorator + version: 5.1.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/decorator-5.1.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 43afe5ab04e35e17ba28649471dd7364 + sha256: 328a6a379f9bdfd0230e51de291ce858e6479411ea4b0545fb377c71662ef3e2 + category: main + optional: false +- name: defusedxml + version: 0.7.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 961b3a227b437d82ad7054484cfa71b2 + sha256: 9717a059677553562a8f38ff07f3b9f61727bd614f505658b0a5ecbcf8df89be + category: main + optional: false +- name: defusedxml + version: 0.7.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 961b3a227b437d82ad7054484cfa71b2 + sha256: 9717a059677553562a8f38ff07f3b9f61727bd614f505658b0a5ecbcf8df89be + category: main + optional: false +- name: dill + version: 0.3.7 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/dill-0.3.7-pyhd8ed1ab_0.conda + hash: + md5: 5e4f3466526c52bc9af2d2353a1460bd + sha256: 4ff20c6be028be2825235631c45d9e4a75bca1de65f8840c02dfb28ea0137c45 + category: main + optional: false +- name: dill + version: 0.3.7 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/dill-0.3.7-pyhd8ed1ab_0.conda + hash: + md5: 5e4f3466526c52bc9af2d2353a1460bd + sha256: 4ff20c6be028be2825235631c45d9e4a75bca1de65f8840c02dfb28ea0137c45 + category: main + optional: false +- name: diskcache + version: 5.6.3 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/diskcache-5.6.3-pyhd8ed1ab_0.conda + hash: + md5: 4c33109f652b5d8c995ab243436c9370 + sha256: 2547a3aa97f0862e55d9d4bbef457b087d35f4bff05766c8169c82719bc61e17 + category: main + optional: false +- name: diskcache + version: 5.6.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/diskcache-5.6.3-pyhd8ed1ab_0.conda + hash: + md5: 4c33109f652b5d8c995ab243436c9370 + sha256: 2547a3aa97f0862e55d9d4bbef457b087d35f4bff05766c8169c82719bc61e17 + category: main + optional: false +- name: distlib + version: 0.3.7 + manager: conda + platform: linux-64 + dependencies: + python: 2.7|>=3.6 + url: https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.7-pyhd8ed1ab_0.conda + hash: + md5: 12d8aae6994f342618443a8f05c652a0 + sha256: 13c887cb4a29e1e853a118cfc0e42b72a7e1d1c50c66c0974885d37f0db30619 + category: main + optional: false +- name: distlib + version: 0.3.7 + manager: conda + platform: osx-arm64 + dependencies: + python: 2.7|>=3.6 + url: https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.7-pyhd8ed1ab_0.conda + hash: + md5: 12d8aae6994f342618443a8f05c652a0 + sha256: 13c887cb4a29e1e853a118cfc0e42b72a7e1d1c50c66c0974885d37f0db30619 + category: main + optional: false +- name: distributed + version: 2023.12.0 + manager: conda + platform: linux-64 + dependencies: + click: '>=8.0' + cloudpickle: '>=1.5.0' + cytoolz: '>=0.10.1' + dask-core: '>=2023.12.0,<2023.12.1.0a0' + jinja2: '>=2.10.3' + locket: '>=1.0.0' + msgpack-python: '>=1.0.0' + packaging: '>=20.0' + psutil: '>=5.7.2' + python: '>=3.9' + pyyaml: '>=5.3.1' + sortedcontainers: '>=2.0.5' + tblib: '>=1.6.0' + toolz: '>=0.10.0' + tornado: '>=6.0.4' + urllib3: '>=1.24.3' + zict: '>=3.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/distributed-2023.12.0-pyhd8ed1ab_0.conda + hash: + md5: 22d620e1079e99c34578cb0c615d2789 + sha256: 7f16084ca5cbc66c4673d1eb032bd49f03a96a846656a18d38fd70fa8f2f16cc + category: main + optional: false +- name: distributed + version: 2023.2.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + click: '>=7.0' + packaging: '>=20.0' + pyyaml: '>=5.3.1' + cloudpickle: '>=1.5.0' + urllib3: '>=1.24.3' + msgpack-python: '>=1.0.0' + toolz: '>=0.10.0' + jinja2: '>=2.10.3' + tblib: '>=1.6.0' + locket: '>=1.0.0' + psutil: '>=5.7.0' + tornado: '>=6.0.3' + sortedcontainers: '>=2.0.5' + cytoolz: '>=0.10.0' + zict: '>=2.1.0' + dask-core: '>=2023.2.0,<2023.2.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/distributed-2023.2.0-pyhd8ed1ab_0.conda + hash: + md5: 908e176bdb542b900f1c044bac70683b + sha256: 5551a2f3d05f3ca595ae93c3c59dbcda13fc0183d49dfb01c84bd482e7ae19a4 + category: main + optional: false +- name: docker-py + version: 6.1.3 + manager: conda + platform: linux-64 + dependencies: + packaging: '>=14.0' + paramiko: '>=2.4.3' + python: '>=3.7' + pywin32-on-windows: '' + requests: '>=2.26.0' + urllib3: '>=1.26.0' + websocket-client: '>=0.32.0' + url: https://conda.anaconda.org/conda-forge/noarch/docker-py-6.1.3-pyhd8ed1ab_0.conda + hash: + md5: c95d23d8bae7e21491868cc7772d7c73 + sha256: 7c3031602e92fd7682302ef98a45bdf7374d48a849cdd3900b7c68a32d162177 + category: main + optional: false +- name: docker-py + version: 6.1.3 + manager: conda + platform: osx-arm64 + dependencies: + pywin32-on-windows: '' + python: '>=3.7' + requests: '>=2.26.0' + urllib3: '>=1.26.0' + websocket-client: '>=0.32.0' + packaging: '>=14.0' + paramiko: '>=2.4.3' + url: https://conda.anaconda.org/conda-forge/noarch/docker-py-6.1.3-pyhd8ed1ab_0.conda + hash: + md5: c95d23d8bae7e21491868cc7772d7c73 + sha256: 7c3031602e92fd7682302ef98a45bdf7374d48a849cdd3900b7c68a32d162177 + category: main + optional: false +- name: docstring_parser + version: '0.15' + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/docstring_parser-0.15-pyhd8ed1ab_0.conda + hash: + md5: 031fcb28b8e80c1f7bec22ccdf4904b2 + sha256: 9b22e1f1d0decc26cc0743ce929e1a7e233fd7921d1b5c390db0691b8042a706 + category: main + optional: false +- name: docstring_parser + version: '0.15' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/docstring_parser-0.15-pyhd8ed1ab_0.conda + hash: + md5: 031fcb28b8e80c1f7bec22ccdf4904b2 + sha256: 9b22e1f1d0decc26cc0743ce929e1a7e233fd7921d1b5c390db0691b8042a706 + category: main + optional: false +- name: docutils + version: 0.17.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/docutils-0.17.1-py39hf3d152e_4.conda + hash: + md5: 0d71b15b6e77f2ae2ef81a478a384ead + sha256: 3205c831e88f49ae5bfea74f3d0b5924f51a7da8b4ad966fe1511ad7dd0be158 + category: main + optional: false +- name: docutils + version: 0.17.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/docutils-0.17.1-py39h2804cbe_4.conda + hash: + md5: e61e7fb2f58fde42339a74370b55c1e9 + sha256: ca7a33d2f83d7760f384f565956d3a79663b33c94cf2753da20150f096dac0bc + category: main + optional: false +- name: entrypoints + version: '0.4' + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/entrypoints-0.4-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 3cf04868fee0a029769bd41f4b2fbf2d + sha256: 2ec4a0900a4a9f42615fc04d0fb3286b796abe56590e8e042f6ec25e102dd5af + category: main + optional: false +- name: entrypoints + version: '0.4' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/entrypoints-0.4-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 3cf04868fee0a029769bd41f4b2fbf2d + sha256: 2ec4a0900a4a9f42615fc04d0fb3286b796abe56590e8e042f6ec25e102dd5af + category: main + optional: false +- name: exceptiongroup + version: 1.2.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_0.conda + hash: + md5: f6c211fee3c98229652b60a9a42ef363 + sha256: cf83dcaf9006015c8ccab3fc6770f478464a66a8769e1763ca5d7dff09d11d08 + category: main + optional: false +- name: exceptiongroup + version: 1.2.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_0.conda + hash: + md5: f6c211fee3c98229652b60a9a42ef363 + sha256: cf83dcaf9006015c8ccab3fc6770f478464a66a8769e1763ca5d7dff09d11d08 + category: main + optional: false +- name: executing + version: 2.0.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/executing-2.0.1-pyhd8ed1ab_0.conda + hash: + md5: e16be50e378d8a4533b989035b196ab8 + sha256: c738804ab1e6376f8ea63372229a04c8d658dc90fd5a218c6273a2eaf02f4057 + category: main + optional: false +- name: executing + version: 2.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/executing-2.0.1-pyhd8ed1ab_0.conda + hash: + md5: e16be50e378d8a4533b989035b196ab8 + sha256: c738804ab1e6376f8ea63372229a04c8d658dc90fd5a218c6273a2eaf02f4057 + category: main + optional: false +- name: expat + version: 2.5.0 + manager: conda + platform: linux-64 + dependencies: + libexpat: 2.5.0 + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/expat-2.5.0-hcb278e6_1.conda + hash: + md5: 8b9b5aca60558d02ddaa09d599e55920 + sha256: 36dfeb4375059b3bba75ce9b38c29c69fd257342a79e6cf20e9f25c1523f785f + category: main + optional: false +- name: expat + version: 2.5.0 + manager: conda + platform: osx-arm64 + dependencies: + libexpat: 2.5.0 + url: https://conda.anaconda.org/conda-forge/osx-arm64/expat-2.5.0-hb7217d7_1.conda + hash: + md5: 624fa0dd6fdeaa650b71a62296fdfedf + sha256: 9f06afbe4604decf6a2e8e7e87f5ca218a3e9049d57d5b3fcd538ca6240d21a0 + category: main + optional: false +- name: fastavro + version: 1.9.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + pytz: '' + url: https://conda.anaconda.org/conda-forge/linux-64/fastavro-1.9.1-py39hd1e30aa_0.conda + hash: + md5: 6222cc87faa7fe48c2cf35920dd7ff28 + sha256: d8ce574d2ba15706a44966e0e5aafdcf25bdaace3f89435590f0b6ee1efe1a91 + category: main + optional: false +- name: fastavro + version: 1.9.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + pytz: '' + url: https://conda.anaconda.org/conda-forge/osx-arm64/fastavro-1.9.1-py39h17cfd9d_0.conda + hash: + md5: a435b41193850bbc3e8e49943b9140e8 + sha256: 1b4944683f3e2dd349c1620406eb1086342efc838d923161ea58a601694ce227 + category: main + optional: false +- name: filelock + version: 3.13.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/filelock-3.13.1-pyhd8ed1ab_0.conda + hash: + md5: 0c1729b74a8152fde6a38ba0a2ab9f45 + sha256: 4d742d91412d1f163e5399d2b50c5d479694ebcd309127abb549ca3977f89d2b + category: main + optional: false +- name: filelock + version: 3.13.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/filelock-3.13.1-pyhd8ed1ab_0.conda + hash: + md5: 0c1729b74a8152fde6a38ba0a2ab9f45 + sha256: 4d742d91412d1f163e5399d2b50c5d479694ebcd309127abb549ca3977f89d2b + category: main + optional: false +- name: fiona + version: 1.9.5 + manager: conda + platform: linux-64 + dependencies: + attrs: '>=17' + click: '>=4.0' + click-plugins: '>=1.0' + cligj: '>=0.5' + gdal: '' + importlib-metadata: '' + libgcc-ng: '>=12' + libgdal: '>=3.8.0,<3.9.0a0' + libstdcxx-ng: '>=12' + munch: '' + numpy: '>=1.22.4,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + setuptools: '' + shapely: '' + six: '>=1.7' + url: https://conda.anaconda.org/conda-forge/linux-64/fiona-1.9.5-py39hcfcd403_1.conda + hash: + md5: 5148d08d3f4866d7f5303955dbaad2d5 + sha256: f13d9be94ee07fe6336a113333c007c4a487149b75cac351fb88dee724e36798 + category: main + optional: false +- name: flask + version: 2.3.3 + manager: conda + platform: linux-64 + dependencies: + blinker: '>=1.6.2' + click: '>=8.1.3' + importlib-metadata: '>=3.6.0' + itsdangerous: '>=2.1.2' + jinja2: '>=3.1.2' + python: '>=3.8' + werkzeug: '>=2.3.7' + url: https://conda.anaconda.org/conda-forge/noarch/flask-2.3.3-pyhd8ed1ab_0.conda + hash: + md5: 9b0d29067484a8dfacfae85b8fba81bc + sha256: 4f84ffdc5471236e8225db86c7508426b46aa2c3802d58ca40b3c3e174533b39 + category: main + optional: false +- name: flask + version: 2.3.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + jinja2: '>=3.1.2' + click: '>=8.1.3' + importlib-metadata: '>=3.6.0' + itsdangerous: '>=2.1.2' + blinker: '>=1.6.2' + werkzeug: '>=2.3.7' + url: https://conda.anaconda.org/conda-forge/noarch/flask-2.3.3-pyhd8ed1ab_0.conda + hash: + md5: 9b0d29067484a8dfacfae85b8fba81bc + sha256: 4f84ffdc5471236e8225db86c7508426b46aa2c3802d58ca40b3c3e174533b39 + category: main + optional: false +- name: flatbuffers + version: 23.5.26 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/flatbuffers-23.5.26-h59595ed_1.conda + hash: + md5: 913a1c6fd00b66f33392a129e835ceca + sha256: 898446f402c14da0e74cd2062e78ebcfbc531e08a8207f4df36dd596d30ccb70 + category: main + optional: false +- name: flatbuffers + version: 23.5.26 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + url: https://conda.anaconda.org/conda-forge/osx-arm64/flatbuffers-23.5.26-h13dd4ca_1.conda + hash: + md5: 789ac6fe52a8b2ce8dade900eb30f482 + sha256: 83b28e6f3c1737f4aa250473ecc77fdcdf2802019b77515d95d95daa55111ad0 + category: main + optional: false +- name: flyteidl + version: 1.10.6 + manager: conda + platform: linux-64 + dependencies: + googleapis-common-protos: '' + protobuf: '>=4.21.1,<5.0.0' + protoc-gen-swagger: '' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/flyteidl-1.10.6-pyhd8ed1ab_0.conda + hash: + md5: 94aef87e09529f57d4454d64f67ade17 + sha256: 2b3db247e15ae613248afceae3b3c291125a21c0220082a260babbf7b061d095 + category: main + optional: false +- name: flyteidl + version: 1.10.6 + manager: conda + platform: osx-arm64 + dependencies: + googleapis-common-protos: '' + protoc-gen-swagger: '' + python: '>=3.8' + protobuf: '>=4.21.1,<5.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/flyteidl-1.10.6-pyhd8ed1ab_0.conda + hash: + md5: 94aef87e09529f57d4454d64f67ade17 + sha256: 2b3db247e15ae613248afceae3b3c291125a21c0220082a260babbf7b061d095 + category: main + optional: false +- name: flytekit + version: 1.10.2 + manager: conda + platform: linux-64 + dependencies: + adlfs: '' + click: '>=6.6,<9.0' + cloudpickle: '>=2.0.0' + cookiecutter: '>=1.7.3' + croniter: '>=0.3.20,<4.0.0' + dataclasses-json: '>=0.5.2,<0.5.12' + diskcache: '>=5.2.1' + docker-py: '>=4.0.0,<7.0.0' + docstring_parser: '>=0.9.0' + flyteidl: '>=1.10.0' + fsspec: '>=2023.3.0,<=2023.9.2' + gcsfs: '' + googleapis-common-protos: '>=1.57' + grpcio: '' + grpcio-status: '' + importlib-metadata: '' + joblib: '' + jsonpickle: '' + keyring: '>=18.0.1' + marshmallow-enum: '' + marshmallow-jsonschema: '>=0.12.0' + mashumaro: '>=3.9.1' + numpy: '' + pandas: '>=1.0.0,<2.0.0' + protobuf: <4.25.0 + pyarrow: '>=4.0.0' + python: '>=3.8,<3.12' + python-json-logger: '>=2.0.0' + python-kubernetes: '>=12.0.1' + pytimeparse: '>=1.1.8,<2.0.0' + pyyaml: '!=6.0.0,!=5.4.0,!=5.4.1' + requests: '>=2.18.4,<3.0.0' + rich: '' + rich-click: '' + s3fs: '>=0.6.0' + statsd: '>=3.0.0,<4.0.0' + typing-extensions: '' + urllib3: '>=1.22,<2.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/flytekit-1.10.2-pyhd8ed1ab_0.conda + hash: + md5: 02846f149ea2ccc8d579e4bf28e86dcf + sha256: 827316c5fe11b43f7c3b0ed74d92f3faf36a7dfd4f33091421e209a0ad544ee9 + category: main + optional: false +- name: flytekit + version: 1.10.2 + manager: conda + platform: osx-arm64 + dependencies: + numpy: '' + typing-extensions: '' + importlib-metadata: '' + joblib: '' + rich: '' + gcsfs: '' + grpcio: '' + jsonpickle: '' + adlfs: '' + rich-click: '' + grpcio-status: '' + marshmallow-enum: '' + python: '>=3.8,<3.12' + diskcache: '>=5.2.1' + pyarrow: '>=4.0.0' + pandas: '>=1.0.0,<2.0.0' + python-json-logger: '>=2.0.0' + cloudpickle: '>=2.0.0' + python-kubernetes: '>=12.0.1' + cookiecutter: '>=1.7.3' + croniter: '>=0.3.20,<4.0.0' + docstring_parser: '>=0.9.0' + keyring: '>=18.0.1' + marshmallow-jsonschema: '>=0.12.0' + pytimeparse: '>=1.1.8,<2.0.0' + requests: '>=2.18.4,<3.0.0' + statsd: '>=3.0.0,<4.0.0' + urllib3: '>=1.22,<2.0.0' + click: '>=6.6,<9.0' + googleapis-common-protos: '>=1.57' + docker-py: '>=4.0.0,<7.0.0' + s3fs: '>=0.6.0' + pyyaml: '!=6.0.0,!=5.4.0,!=5.4.1' + dataclasses-json: '>=0.5.2,<0.5.12' + fsspec: '>=2023.3.0,<=2023.9.2' + mashumaro: '>=3.9.1' + flyteidl: '>=1.10.0' + protobuf: <4.25.0 + url: https://conda.anaconda.org/conda-forge/noarch/flytekit-1.10.2-pyhd8ed1ab_0.conda + hash: + md5: 02846f149ea2ccc8d579e4bf28e86dcf + sha256: 827316c5fe11b43f7c3b0ed74d92f3faf36a7dfd4f33091421e209a0ad544ee9 + category: main + optional: false +- name: folium + version: 0.15.1 + manager: conda + platform: linux-64 + dependencies: + branca: '>=0.7.0' + jinja2: '>=2.9' + numpy: '' + python: '>=3.7' + requests: '' + xyzservices: '' + url: https://conda.anaconda.org/conda-forge/noarch/folium-0.15.1-pyhd8ed1ab_0.conda + hash: + md5: 4fdfc338f6fb875b1078a7e20dbc99e2 + sha256: c0730ddfaf35e39ac92b7fd07315843e7948b2ce3361d164ec1b722dd0440c2b + category: main + optional: false +- name: font-ttf-dejavu-sans-mono + version: '2.37' + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + hash: + md5: 0c96522c6bdaed4b1566d11387caaf45 + sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b + category: main + optional: false +- name: font-ttf-dejavu-sans-mono + version: '2.37' + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + hash: + md5: 0c96522c6bdaed4b1566d11387caaf45 + sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b + category: main + optional: false +- name: font-ttf-inconsolata + version: '3.000' + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + hash: + md5: 34893075a5c9e55cdafac56607368fc6 + sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c + category: main + optional: false +- name: font-ttf-inconsolata + version: '3.000' + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + hash: + md5: 34893075a5c9e55cdafac56607368fc6 + sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c + category: main + optional: false +- name: font-ttf-source-code-pro + version: '2.038' + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + hash: + md5: 4d59c254e01d9cde7957100457e2d5fb + sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 + category: main + optional: false +- name: font-ttf-source-code-pro + version: '2.038' + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + hash: + md5: 4d59c254e01d9cde7957100457e2d5fb + sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 + category: main + optional: false +- name: font-ttf-ubuntu + version: '0.83' + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_1.conda + hash: + md5: 6185f640c43843e5ad6fd1c5372c3f80 + sha256: 056c85b482d58faab5fd4670b6c1f5df0986314cca3bc831d458b22e4ef2c792 + category: main + optional: false +- name: font-ttf-ubuntu + version: '0.83' + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_1.conda + hash: + md5: 6185f640c43843e5ad6fd1c5372c3f80 + sha256: 056c85b482d58faab5fd4670b6c1f5df0986314cca3bc831d458b22e4ef2c792 + category: main + optional: false +- name: fontconfig + version: 2.14.2 + manager: conda + platform: linux-64 + dependencies: + expat: '>=2.5.0,<3.0a0' + freetype: '>=2.12.1,<3.0a0' + libgcc-ng: '>=12' + libuuid: '>=2.32.1,<3.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.2-h14ed4e7_0.conda + hash: + md5: 0f69b688f52ff6da70bccb7ff7001d1d + sha256: 155d534c9037347ea7439a2c6da7c24ffec8e5dd278889b4c57274a1d91e0a83 + category: main + optional: false +- name: fontconfig + version: 2.14.2 + manager: conda + platform: osx-arm64 + dependencies: + expat: '>=2.5.0,<3.0a0' + freetype: '>=2.12.1,<3.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/fontconfig-2.14.2-h82840c6_0.conda + hash: + md5: f77d47ddb6d3cc5b39b9bdf65635afbb + sha256: 7094917fc6758186e17c61d8ee8fd2bbbe9f303b4addac61d918fa415c497e2b + category: main + optional: false +- name: fonts-conda-ecosystem + version: '1' + manager: conda + platform: linux-64 + dependencies: + fonts-conda-forge: '' + url: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + hash: + md5: fee5683a3f04bd15cbd8318b096a27ab + sha256: a997f2f1921bb9c9d76e6fa2f6b408b7fa549edd349a77639c9fe7a23ea93e61 + category: main + optional: false +- name: fonts-conda-ecosystem + version: '1' + manager: conda + platform: osx-arm64 + dependencies: + fonts-conda-forge: '' + url: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + hash: + md5: fee5683a3f04bd15cbd8318b096a27ab + sha256: a997f2f1921bb9c9d76e6fa2f6b408b7fa549edd349a77639c9fe7a23ea93e61 + category: main + optional: false +- name: fonts-conda-forge + version: '1' + manager: conda + platform: linux-64 + dependencies: + font-ttf-dejavu-sans-mono: '' + font-ttf-inconsolata: '' + font-ttf-source-code-pro: '' + font-ttf-ubuntu: '' + url: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 + hash: + md5: f766549260d6815b0c52253f1fb1bb29 + sha256: 53f23a3319466053818540bcdf2091f253cbdbab1e0e9ae7b9e509dcaa2a5e38 + category: main + optional: false +- name: fonts-conda-forge + version: '1' + manager: conda + platform: osx-arm64 + dependencies: + font-ttf-inconsolata: '' + font-ttf-source-code-pro: '' + font-ttf-ubuntu: '' + font-ttf-dejavu-sans-mono: '' + url: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 + hash: + md5: f766549260d6815b0c52253f1fb1bb29 + sha256: 53f23a3319466053818540bcdf2091f253cbdbab1e0e9ae7b9e509dcaa2a5e38 + category: main + optional: false +- name: fonttools + version: 4.46.0 + manager: conda + platform: linux-64 + dependencies: + brotli: '' + libgcc-ng: '>=12' + munkres: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + unicodedata2: '>=14.0.0' + url: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.46.0-py39hd1e30aa_0.conda + hash: + md5: 9b58e5973dd3d786253f4ca9534b1aba + sha256: e0d0b4039efce99870b8bd07a5a1bb7700b75a570ab19a38862336218ba66b94 + category: main + optional: false +- name: fonttools + version: 4.46.0 + manager: conda + platform: osx-arm64 + dependencies: + brotli: '' + munkres: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + unicodedata2: '>=14.0.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.46.0-py39h17cfd9d_0.conda + hash: + md5: 92cd73c1c1b85f06797dfde1d79a937b + sha256: 1e16d1a54a16af7ddd5a16f7988bf2d371fb3fd78bd95ab7937eff68e1907d74 + category: main + optional: false +- name: fqdn + version: 1.5.1 + manager: conda + platform: linux-64 + dependencies: + cached-property: '>=1.3.0' + python: '>=2.7,<4' + url: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 642d35437078749ef23a5dca2c9bb1f3 + sha256: 6cfd1f9bcd2358a69fb571f4b3af049b630d52647d906822dbedac03e84e4f63 + category: main + optional: false +- name: fqdn + version: 1.5.1 + manager: conda + platform: osx-arm64 + dependencies: + cached-property: '>=1.3.0' + python: '>=2.7,<4' + url: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 642d35437078749ef23a5dca2c9bb1f3 + sha256: 6cfd1f9bcd2358a69fb571f4b3af049b630d52647d906822dbedac03e84e4f63 + category: main + optional: false +- name: freetype + version: 2.12.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libpng: '>=1.6.39,<1.7.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda + hash: + md5: 9ae35c3d96db2c94ce0cef86efdfa2cb + sha256: b2e3c449ec9d907dd4656cb0dc93e140f447175b125a3824b31368b06c666bb6 + category: main + optional: false +- name: freetype + version: 2.12.1 + manager: conda + platform: osx-arm64 + dependencies: + libpng: '>=1.6.39,<1.7.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.12.1-hadb7bae_2.conda + hash: + md5: e6085e516a3e304ce41a8ee08b9b89ad + sha256: 791673127e037a2dc0eebe122dc4f904cb3f6e635bb888f42cbe1a76b48748d9 + category: main + optional: false +- name: freexl + version: 2.0.0 + manager: conda + platform: linux-64 + dependencies: + libexpat: '>=2.5.0,<3.0a0' + libgcc-ng: '>=12' + libiconv: '>=1.17,<2.0a0' + minizip: '>=4.0.1,<5.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/freexl-2.0.0-h743c826_0.conda + hash: + md5: 12e6988845706b2cfbc3bc35c9a61a95 + sha256: 9213f60ba710ecfd3632ce47e036775c9f15ce80a6682ff63cbf12d9dddd5382 + category: main + optional: false +- name: fribidi + version: 1.0.10 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=7.5.0' + url: https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.10-h36c2ea0_0.tar.bz2 + hash: + md5: ac7bc6a654f8f41b352b38f4051135f8 + sha256: 5d7b6c0ee7743ba41399e9e05a58ccc1cfc903942e49ff6f677f6e423ea7a627 + category: main + optional: false +- name: fribidi + version: 1.0.10 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/fribidi-1.0.10-h27ca646_0.tar.bz2 + hash: + md5: c64443234ff91d70cb9c7dc926c58834 + sha256: 4b37ea851a2cf85edf0a63d2a63266847ec3dcbba4a31156d430cdd6aa811303 + category: main + optional: false +- name: frozendict + version: 2.3.10 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/frozendict-2.3.10-py39hd1e30aa_3.conda + hash: + md5: 252562a446a331682c5101ee16fd8988 + sha256: 05b9f884d59b0978ef426c3a5e8791b28478e394be3ad52ac25bbfe0474ac6db + category: main + optional: false +- name: frozendict + version: 2.3.10 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/frozendict-2.3.10-py39h17cfd9d_3.conda + hash: + md5: 6d5a1b15362833f5b308f56916d517ba + sha256: 1022b48e9380276276efcf8718669e29c96ec0f291df5af01fe7954a6ed82673 + category: main + optional: false +- name: frozenlist + version: 1.4.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/frozenlist-1.4.0-py39hd1e30aa_1.conda + hash: + md5: 5ccdccec4ed5576ae7382e33cd343dc2 + sha256: f1d0981597be0e7f78c4454517e16e09f0c7290af30e0e705a5a6a4952cf7bdd + category: main + optional: false +- name: frozenlist + version: 1.4.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/frozenlist-1.4.0-py39h0f82c59_1.conda + hash: + md5: c99be6ea61e4ab92239474db7eeae799 + sha256: aec9bcbf3a23064bc72fb9c0018b626293843c519ceb11e5715537ddb5bff226 + category: main + optional: false +- name: fsspec + version: 2023.9.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/fsspec-2023.9.2-pyh1a96a4e_0.conda + hash: + md5: 9d15cd3a0e944594ab528da37dc72ecc + sha256: d95d11d1f501cb69528bb2b620b728f12caf872cb23837bc9bdd6ef405b4ecfb + category: main + optional: false +- name: fsspec + version: 2023.9.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/fsspec-2023.9.2-pyh1a96a4e_0.conda + hash: + md5: 9d15cd3a0e944594ab528da37dc72ecc + sha256: d95d11d1f501cb69528bb2b620b728f12caf872cb23837bc9bdd6ef405b4ecfb + category: main + optional: false +- name: furo + version: 2023.5.20 + manager: conda + platform: linux-64 + dependencies: + beautifulsoup4: '' + myst-parser: '' + pygments: '>=2.7' + python: '>=3.6' + sphinx: '>=4' + sphinx-basic-ng: '' + sphinx-inline-tabs: '' + url: https://conda.anaconda.org/conda-forge/noarch/furo-2023.5.20-pyhd8ed1ab_0.conda + hash: + md5: 786e474a83de249aecf767102d7fd87d + sha256: 3513f6e2bc2036e6941b30dd03ea9c98a452e0d311d7dc5d1b45be87e145e3d3 + category: main + optional: false +- name: furo + version: 2023.5.20 + manager: conda + platform: osx-arm64 + dependencies: + beautifulsoup4: '' + myst-parser: '' + sphinx-inline-tabs: '' + sphinx-basic-ng: '' + python: '>=3.6' + sphinx: '>=4' + pygments: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/furo-2023.5.20-pyhd8ed1ab_0.conda + hash: + md5: 786e474a83de249aecf767102d7fd87d + sha256: 3513f6e2bc2036e6941b30dd03ea9c98a452e0d311d7dc5d1b45be87e145e3d3 + category: main + optional: false +- name: future + version: 0.18.3 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/future-0.18.3-pyhd8ed1ab_0.conda + hash: + md5: fec8329fc739090f26a7d7803db254f1 + sha256: b3d34bf4924cb80363c1ab57ac821393f118ffaa94f05368bf4044941163b65e + category: main + optional: false +- name: future + version: 0.18.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/future-0.18.3-pyhd8ed1ab_0.conda + hash: + md5: fec8329fc739090f26a7d7803db254f1 + sha256: b3d34bf4924cb80363c1ab57ac821393f118ffaa94f05368bf4044941163b65e + category: main + optional: false +- name: gast + version: 0.5.4 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.4' + url: https://conda.anaconda.org/conda-forge/noarch/gast-0.5.4-pyhd8ed1ab_0.conda + hash: + md5: 8189adbad784030b76bbf81c68d7b0d4 + sha256: e029d50d55f8fe8cf9323045f84416b7af50e25a0dc1b978f8ba6b9ca8d53ca7 + category: main + optional: false +- name: gast + version: 0.5.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.4' + url: https://conda.anaconda.org/conda-forge/noarch/gast-0.5.4-pyhd8ed1ab_0.conda + hash: + md5: 8189adbad784030b76bbf81c68d7b0d4 + sha256: e029d50d55f8fe8cf9323045f84416b7af50e25a0dc1b978f8ba6b9ca8d53ca7 + category: main + optional: false +- name: gcsfs + version: 2023.9.2 + manager: conda + platform: linux-64 + dependencies: + aiohttp: '' + decorator: '>4.1.2' + fsspec: 2023.9.2 + google-auth: '>=1.2' + google-auth-oauthlib: '' + google-cloud-storage: '>1.40' + python: '>=3.7' + requests: '' + url: https://conda.anaconda.org/conda-forge/noarch/gcsfs-2023.9.2-pyhd8ed1ab_0.conda + hash: + md5: c9deedf93585c3d5ce5525a89bf7287e + sha256: 54a7de26739f764159e7799b83a7b4c135e684c5220a9ca853e7cfe2b6d636f6 + category: main + optional: false +- name: gcsfs + version: 2023.9.2 + manager: conda + platform: osx-arm64 + dependencies: + requests: '' + aiohttp: '' + google-auth-oauthlib: '' + python: '>=3.7' + google-auth: '>=1.2' + decorator: '>4.1.2' + google-cloud-storage: '>1.40' + fsspec: 2023.9.2 + url: https://conda.anaconda.org/conda-forge/noarch/gcsfs-2023.9.2-pyhd8ed1ab_0.conda + hash: + md5: c9deedf93585c3d5ce5525a89bf7287e + sha256: 54a7de26739f764159e7799b83a7b4c135e684c5220a9ca853e7cfe2b6d636f6 + category: main + optional: false +- name: gdal + version: 3.8.0 + manager: conda + platform: linux-64 + dependencies: + hdf5: '>=1.14.2,<1.14.3.0a0' + libgcc-ng: '>=12' + libgdal: 3.8.0 + libstdcxx-ng: '>=12' + libxml2: '>=2.11.6,<2.12.0a0' + numpy: '>=1.22.4,<2.0a0' + openssl: '>=3.1.4,<4.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/gdal-3.8.0-py39h41b90d8_6.conda + hash: + md5: b2eb8b963da5fb12b150a99d9f52f62d + sha256: fd301be7bccb0e912169059dfb69678a15815be646269b1d91b4ddf5ad5f821f + category: main + optional: false +- name: gdk-pixbuf + version: 2.42.10 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libglib: '>=2.78.0,<3.0a0' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.42.10-h829c605_4.conda + hash: + md5: 252a696860674caf7a855e16f680d63a + sha256: 884992d0665a0a5c728943d99b5fba30fd6911bb84eee622fa7ad8a4fa9f6cf7 + category: main + optional: false +- name: gdk-pixbuf + version: 2.42.10 + manager: conda + platform: osx-arm64 + dependencies: + libglib: '>=2.78.0,<3.0a0' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/gdk-pixbuf-2.42.10-h15fa40c_4.conda + hash: + md5: ed5cfaa924087471c439d94a0e393364 + sha256: d0ec06b17a6c9aa13e56b7ce188b061ffb11f5e964cade7e4757156dca2aa5a7 + category: main + optional: false +- name: geopandas + version: 0.14.1 + manager: conda + platform: linux-64 + dependencies: + fiona: '>=1.8.21' + folium: '' + geopandas-base: 0.14.1 + mapclassify: '>=2.4.0' + matplotlib-base: '' + python: '>=3.9' + rtree: '' + xyzservices: '' + url: https://conda.anaconda.org/conda-forge/noarch/geopandas-0.14.1-pyhd8ed1ab_0.conda + hash: + md5: 6ce5f89fb1e2aa7e04d12c0008b3a745 + sha256: f3563ad6f1a55587c097337ece863e583c796c9a9df3ecb396bbfeec4ec309fb + category: main + optional: false +- name: geopandas-base + version: 0.14.1 + manager: conda + platform: linux-64 + dependencies: + packaging: '' + pandas: '>=1.4.0' + pyproj: '>=3.3.0' + python: '>=3.9' + shapely: '>=1.8.0' + url: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-0.14.1-pyha770c72_0.conda + hash: + md5: d65c6f458bfdaa181f388d91e858ea67 + sha256: c813004bb84e50de19f599b188719e40106c858c7da22e504b29ce66e5043361 + category: main + optional: false +- name: geos + version: 3.12.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/geos-3.12.1-h59595ed_0.conda + hash: + md5: 8c0f4f71f5a59ceb0c6fa9f51501066d + sha256: 2593b255cb9c4639d6ea261c47aaed1380216a366546f0468e95c36c2afd1c1a + category: main + optional: false +- name: geotiff + version: 1.7.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libstdcxx-ng: '>=12' + libtiff: '>=4.6.0,<4.7.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + proj: '>=9.3.0,<9.3.1.0a0' + zlib: '' + url: https://conda.anaconda.org/conda-forge/linux-64/geotiff-1.7.1-hf074850_14.conda + hash: + md5: 1d53ee057d8481bd2b4c2c34c8e92aac + sha256: b00958767cb5607bdb3bbcec0b2056b3e48c0f9e34c31ed8ac01c9bd36704dab + category: main + optional: false +- name: gettext + version: 0.21.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/gettext-0.21.1-h27087fc_0.tar.bz2 + hash: + md5: 14947d8770185e5153fdd04d4673ed37 + sha256: 4fcfedc44e4c9a053f0416f9fc6ab6ed50644fca3a761126dbd00d09db1f546a + category: main + optional: false +- name: gettext + version: 0.21.1 + manager: conda + platform: osx-arm64 + dependencies: + libiconv: '>=1.17,<2.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/gettext-0.21.1-h0186832_0.tar.bz2 + hash: + md5: 63d2ff6fddfa74e5458488fd311bf635 + sha256: 093b2f96dc4b48e4952ab8946facec98b34b708a056251fc19c23c3aad30039e + category: main + optional: false +- name: gflags + version: 2.2.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=7.5.0' + libstdcxx-ng: '>=7.5.0' + url: https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-he1b5a44_1004.tar.bz2 + hash: + md5: cddaf2c63ea4a5901cf09524c490ecdc + sha256: a853c0cacf53cfc59e1bca8d6e5cdfe9f38fce836f08c2a69e35429c2a492e77 + category: main + optional: false +- name: gflags + version: 2.2.2 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=11.0.0.rc1' + url: https://conda.anaconda.org/conda-forge/osx-arm64/gflags-2.2.2-hc88da5d_1004.tar.bz2 + hash: + md5: aab9ddfad863e9ef81229a1f8852211b + sha256: 25d4a20af2e5ace95fdec88970f6d190e77e20074d2f6d3cef766198b76a4289 + category: main + optional: false +- name: giflib + version: 5.2.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.1-h0b41bf4_3.conda + hash: + md5: 96f3b11872ef6fad973eac856cd2624f + sha256: 41ec165704ccce2faa0437f4f53c03c06261a2cc9ff7614828e51427d9261f4b + category: main + optional: false +- name: giflib + version: 5.2.1 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/giflib-5.2.1-h1a8c8d9_3.conda + hash: + md5: f39a05d3dbb0e5024b7deabb2c0993f1 + sha256: dbf1e431d3e5e03f8eeb77ec08a4c5d6d5d9af84dbef13d4365e397dd389beb8 + category: main + optional: false +- name: gitdb + version: 4.0.11 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + smmap: '>=3.0.1,<6' + url: https://conda.anaconda.org/conda-forge/noarch/gitdb-4.0.11-pyhd8ed1ab_0.conda + hash: + md5: 623b19f616f2ca0c261441067e18ae40 + sha256: 52ab2798be31b8f509eeec458712f447ced4f96ecb672c6c9a42778f47e07b1b + category: main + optional: false +- name: gitdb + version: 4.0.11 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + smmap: '>=3.0.1,<6' + url: https://conda.anaconda.org/conda-forge/noarch/gitdb-4.0.11-pyhd8ed1ab_0.conda + hash: + md5: 623b19f616f2ca0c261441067e18ae40 + sha256: 52ab2798be31b8f509eeec458712f447ced4f96ecb672c6c9a42778f47e07b1b + category: main + optional: false +- name: gitpython + version: 3.1.40 + manager: conda + platform: linux-64 + dependencies: + gitdb: '>=4.0.1,<5' + python: '>=3.7' + typing_extensions: '>=3.7.4.3' + url: https://conda.anaconda.org/conda-forge/noarch/gitpython-3.1.40-pyhd8ed1ab_0.conda + hash: + md5: 6bf74c3b7c13079a91d4bd3da51cefcf + sha256: 6b85809ffbfe5c1887b674bf0492cc4dd1ac8a25f4d9fa20ef404be92186259b + category: main + optional: false +- name: gitpython + version: 3.1.40 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + typing_extensions: '>=3.7.4.3' + gitdb: '>=4.0.1,<5' + url: https://conda.anaconda.org/conda-forge/noarch/gitpython-3.1.40-pyhd8ed1ab_0.conda + hash: + md5: 6bf74c3b7c13079a91d4bd3da51cefcf + sha256: 6b85809ffbfe5c1887b674bf0492cc4dd1ac8a25f4d9fa20ef404be92186259b + category: main + optional: false +- name: glog + version: 0.6.0 + manager: conda + platform: linux-64 + dependencies: + gflags: '>=2.2.2,<2.3.0a0' + libgcc-ng: '>=10.3.0' + libstdcxx-ng: '>=10.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2 + hash: + md5: b31f3565cb84435407594e548a2fb7b2 + sha256: 888cbcfb67f6e3d88a4c4ab9d26c9a406f620c4101a35dc6d2dbadb95f2221d4 + category: main + optional: false +- name: glog + version: 0.6.0 + manager: conda + platform: osx-arm64 + dependencies: + gflags: '>=2.2.2,<2.3.0a0' + libcxx: '>=12.0.1' + url: https://conda.anaconda.org/conda-forge/osx-arm64/glog-0.6.0-h6da1cb0_0.tar.bz2 + hash: + md5: 5a570729c7709399cf8511aeeda6f989 + sha256: 4d772c42477f64be708594ac45870feba3e838977871118eb25e00deb0e9a73c + category: main + optional: false +- name: gmp + version: 6.3.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-h59595ed_0.conda + hash: + md5: 0e33ef437202db431aa5a928248cf2e8 + sha256: 2a50495b6bbbacb03107ea0b752d8358d4a40b572d124a8cade068c147f344f5 + category: main + optional: false +- name: gmp + version: 6.3.0 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + libcxx: '>=16.0.6' + url: https://conda.anaconda.org/conda-forge/osx-arm64/gmp-6.3.0-h965bd2d_0.conda + hash: + md5: bb8f17b25ebdb9d8819c2c5bf3ccb180 + sha256: d13f09ba46dc4732a3513da76da2352b9a6b71376dc3ba8210bbf1ca0c2e51e3 + category: main + optional: false +- name: gmpy2 + version: 2.1.2 + manager: conda + platform: linux-64 + dependencies: + gmp: '>=6.2.1,<7.0a0' + libgcc-ng: '>=12' + mpc: '>=1.2.1,<2.0a0' + mpfr: '>=4.1.0,<5.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.1.2-py39h376b7d2_1.tar.bz2 + hash: + md5: d019ebf9a328e19c211be7e916c57b80 + sha256: f5a5ab463d7d9e9c4f6a70748adf334ad28072c9befe4748d0eaa48fccc24d56 + category: main + optional: false +- name: gmpy2 + version: 2.1.2 + manager: conda + platform: osx-arm64 + dependencies: + gmp: '>=6.2.1,<7.0a0' + mpc: '>=1.2.1,<2.0a0' + mpfr: '>=4.1.0,<5.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.1.2-py39h0b4f9c6_1.tar.bz2 + hash: + md5: 3b2112b0ed20ffbc93021b5aef9c7f30 + sha256: 2ca5b67459b61b6f8df07bda10ffc5732ad54f24fe1f81890be3409495f7a55e + category: main + optional: false +- name: google-api-core + version: 2.14.0 + manager: conda + platform: linux-64 + dependencies: + google-auth: '>=2.14.1,<3.0.dev0' + googleapis-common-protos: '>=1.56.2,<2.0.dev0' + protobuf: '>=3.19.5,<5.0.0.dev0,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5' + python: '>=3.7' + requests: '>=2.18.0,<3.0.0.dev0' + url: https://conda.anaconda.org/conda-forge/noarch/google-api-core-2.14.0-pyhd8ed1ab_0.conda + hash: + md5: cebe18c719a6818849b921748aa91750 + sha256: 4bc666e51fe40266435b8e8a4137e47278e044ca26be34c05260236552914ebc + category: main + optional: false +- name: google-api-core + version: 1.31.5 + manager: conda + platform: osx-arm64 + dependencies: + pytz: '' + python: '>=3.6' + packaging: '>=14.3' + protobuf: '>=3.12.0' + requests: '>=2.18.0,<3.0.0dev' + six: '>=1.13.0' + setuptools: '>=40.3.0' + googleapis-common-protos: '>=1.6.0,<2.0dev' + google-auth: '>=1.25.1,<2.0dev' + url: https://conda.anaconda.org/conda-forge/noarch/google-api-core-1.31.5-pyhd8ed1ab_0.tar.bz2 + hash: + md5: af0e65ba5f2c0a20e1f93afa747b24d4 + sha256: d83b1e199b96ada107176d6ea35f6349208be15c0410c027f2b844e76d8fea8c + category: main + optional: false +- name: google-api-core-grpc + version: 2.14.0 + manager: conda + platform: linux-64 + dependencies: + google-api-core: 2.14.0 + grpcio: '>=1.49.1,<2.0.dev0' + grpcio-status: '>=1.49.1,<2.0.dev0' + url: https://conda.anaconda.org/conda-forge/noarch/google-api-core-grpc-2.14.0-hd8ed1ab_0.conda + hash: + md5: 07673e1c11693ba1e38ffda0f4260c4b + sha256: 8b0de79db956df9539306b080fcd334e986cf83aebbd70610a1bb4473e5d2690 + category: main + optional: false +- name: google-api-core-grpc + version: 1.31.5 + manager: conda + platform: osx-arm64 + dependencies: + google-api-core: 1.31.5 + grpcio: '>=1.29.0,<2.0dev' + url: https://conda.anaconda.org/conda-forge/noarch/google-api-core-grpc-1.31.5-hd8ed1ab_0.tar.bz2 + hash: + md5: 573b8600ceb7268af0505d317a9c4593 + sha256: 63348d84415eb0a6cf13f8df71a39749e44f1eb5b176169f441ce79d43642d76 + category: main + optional: false +- name: google-auth + version: 2.24.0 + manager: conda + platform: linux-64 + dependencies: + aiohttp: '>=3.6.2,<4.0.0' + cachetools: '>=2.0.0,<6.0' + cryptography: '>=38.0.3' + pyasn1-modules: '>=0.2.1' + pyopenssl: '>=20.0.0' + python: '>=3.7' + pyu2f: '>=0.1.5' + requests: '>=2.20.0,<3.0.0' + rsa: '>=3.1.4,<5' + url: https://conda.anaconda.org/conda-forge/noarch/google-auth-2.24.0-pyhca7485f_0.conda + hash: + md5: 5c80374ea4c24d3bd6822108d43715d0 + sha256: c270d1866bd01f3fa97e5c65496b853af6b1c8d58479132c8b3397534fbb2919 + category: main + optional: false +- name: google-auth + version: 1.35.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + six: '>=1.9.0' + setuptools: '>=40.3.0' + pyasn1-modules: '>=0.2.1' + rsa: '>=3.1.4,<5' + aiohttp: '>=3.6.2,<4.0.0dev' + pyopenssl: '>=20.0.0' + pyu2f: '>=0.1.5' + cachetools: '>=2.0.0,<5.0' + requests: '>=2.20.0,<3.0.0dev' + url: https://conda.anaconda.org/conda-forge/noarch/google-auth-1.35.0-pyh6c4a22f_0.tar.bz2 + hash: + md5: e9e51ec25b36547a4192a1953df66a8c + sha256: 1b6690da2eb8026255c22024ef29c0c5c4bfd03d7ebb2be588ec6e6e0d3fedef + category: main + optional: false +- name: google-auth-oauthlib + version: 1.0.0 + manager: conda + platform: linux-64 + dependencies: + click: '>=6.0.0' + google-auth: '>=2.15.0' + python: '>=3.6' + requests-oauthlib: '>=0.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/google-auth-oauthlib-1.0.0-pyhd8ed1ab_1.conda + hash: + md5: 569e62e95b01b53e4ec7d9abe83b7385 + sha256: f89613643658a51a1ac0fb7c7950526fadc2a6ce1ae13755d786e14cfce1633c + category: main + optional: false +- name: google-auth-oauthlib + version: 1.0.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + google-auth: '>=1.0.0' + requests-oauthlib: '>=0.7.0' + click: '>=6.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/google-auth-oauthlib-1.0.0-pyhd8ed1ab_0.conda + hash: + md5: 5ba9d95acb9add67f468ecdee6595c0f + sha256: ef8edcbc8efe616d0f3686607f445a6a96f3549ce2faed1797ad35ca5cd42e81 + category: main + optional: false +- name: google-cloud-bigquery + version: 3.13.0 + manager: conda + platform: linux-64 + dependencies: + db-dtypes: '>=0.3.0,<2.0.0dev' + geopandas: '>=0.9.0,<1.0dev' + google-cloud-bigquery-core: 3.13.0 + google-cloud-bigquery-storage: '>=2.6.0,<3.0.0dev' + grpcio: '>=1.49.1,<2.0dev' + ipykernel: '>=6.0.0' + ipython: '>=7.23.1,!=8.1.0' + ipywidgets: '>=7.7.0' + pandas: '>=1.1.0' + pyarrow: '>=3.0.0' + python: '>=3.7' + shapely: '>=1.8.4,<3.0.0dev' + tqdm: '>=4.7.4,<=5.0.0dev' + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-bigquery-3.13.0-pyhd8ed1ab_0.conda + hash: + md5: f29bc89c0c791c9c6d5c3ba5bfbd67c6 + sha256: 0f3a7a88db5c3f96a0fa57d825af2ff6437e35b447bd10bb3576d2b356ac79d1 + category: main + optional: false +- name: google-cloud-bigquery + version: 2.1.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + pandas: '' + tqdm: '' + ipython: '' + pyarrow: '' + google-cloud-bigquery-storage: '' + google-cloud-bigquery-core: 2.1.0.* + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-bigquery-2.1.0-pyhc8dfbb8_0.tar.bz2 + hash: + md5: 76096cc06c50cd55befc824e38e1f272 + sha256: b6035e801b629f4eb1606d0a4e2a61050760a456fe1a891c048abd9366ad8853 + category: main + optional: false +- name: google-cloud-bigquery-core + version: 3.13.0 + manager: conda + platform: linux-64 + dependencies: + google-api-core-grpc: '>=1.31.5,<3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0' + google-cloud-core: '>=1.6.0,<3.0.0dev' + google-resumable-media: '>=0.6.0,<3.0dev' + grpcio: '>=1.49.1,<2.0dev' + packaging: '>=20.0.0' + proto-plus: '>=1.15.0,<2.0.0dev' + protobuf: '>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5' + python: '>=3.7' + python-dateutil: '>=2.7.2,<3.0dev' + requests: '>=2.21.0,<3.0.0dev' + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-bigquery-core-3.13.0-pyhd8ed1ab_0.conda + hash: + md5: f05b90386980b866877bdd3d4d747455 + sha256: 4dda476ec4af371792c743fecc80c7e11dfd47eb3c9a280b87cf9fc1887a2ff1 + category: main + optional: false +- name: google-cloud-bigquery-core + version: 2.1.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + proto-plus: '>=1.10.0' + google-resumable-media: '>=0.6.0,<2.0dev' + google-api-core-grpc: '>=1.22.2,<2.0.0dev' + google-cloud-core: '>=1.4.1,<2.0.0dev' + six: '>=1.13.0,<2.0.0dev' + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-bigquery-core-2.1.0-pyhc8dfbb8_0.tar.bz2 + hash: + md5: b5aac884e34b3931bfcd3976bb4ba540 + sha256: f487e6b27c00262e85db29ae7d5e629e70ffd1bdb4a52ad8ca3c6cf3b8a8843e + category: main + optional: false +- name: google-cloud-bigquery-storage + version: 2.22.0 + manager: conda + platform: linux-64 + dependencies: + fastavro: '>=0.21.2' + google-cloud-bigquery-storage-core: 2.22.0.* + pandas: '>=0.21.1' + pyarrow: '>=0.15.0' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-bigquery-storage-2.22.0-pyh1a96a4e_0.conda + hash: + md5: 14a5213a076993679239aa0f07334ecd + sha256: b8777b626962e1912f8592e093d318699f7e42752ef90e85f68bc2fab01f7c2c + category: main + optional: false +- name: google-cloud-bigquery-storage + version: 2.11.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + pyarrow: '>=0.15.0' + fastavro: '>=0.21.2' + pandas: '>=0.21.1' + google-cloud-bigquery-storage-core: 2.11.0.* + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-bigquery-storage-2.11.0-pyh6c4a22f_0.tar.bz2 + hash: + md5: 28ef07a4101ddea28bf766b95fc25128 + sha256: 26ac57129328803602c6e199c8b98f31dca7407d4bb7c42d3876baa98ac9f90c + category: main + optional: false +- name: google-cloud-bigquery-storage-core + version: 2.22.0 + manager: conda + platform: linux-64 + dependencies: + google-api-core-grpc: '>=1.34.0,<3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*' + proto-plus: '>=1.22.0,<2.0.0dev' + protobuf: '>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-bigquery-storage-core-2.22.0-pyh1a96a4e_0.conda + hash: + md5: 0869ea717d694cac0fbcd494a6f987c9 + sha256: 8af06f60b2c47cf882755a295d1a8168be978d712abba491d003bbf1a20ca62f + category: main + optional: false +- name: google-cloud-bigquery-storage-core + version: 2.11.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + libcst: '>=0.2.5' + google-api-core-grpc: '>=1.28.0,<3.0.0dev' + proto-plus: '>=1.18.0' + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-bigquery-storage-core-2.11.0-pyh6c4a22f_0.tar.bz2 + hash: + md5: 4e756999f22c7c02dc9f004ad1906b74 + sha256: 9597b1af93ef3182112c140fa26832568a6753f95b1c00371597fe3e7d72b672 + category: main + optional: false +- name: google-cloud-core + version: 2.3.3 + manager: conda + platform: linux-64 + dependencies: + google-api-core: '>=1.31.6,<3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0' + google-auth: '>=1.25.0,<3.0dev' + grpcio: '>=1.38.0,<2.0.0dev' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-core-2.3.3-pyhd8ed1ab_0.conda + hash: + md5: a26b1fa8555cc1d2f0f7ff9985303e66 + sha256: e8a840361b23ca7a9cfa62c1885fc66aa5ad94e48556782e9a032678c9f4b76e + category: main + optional: false +- name: google-cloud-core + version: 1.7.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + six: '>=1.12.0' + grpcio: '>=1.8.2,<2.0.0dev' + google-api-core: '>=1.21.0,<2.0.0dev' + google-auth: '>=1.24.0,<2.0.0dev' + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-core-1.7.2-pyh6c4a22f_0.tar.bz2 + hash: + md5: 97a1d5a5ad03a43f3441b532184dfdc5 + sha256: 7200e42189315445a2c319399f5edad415c93380fbba07146ccbe499558dc5e6 + category: main + optional: false +- name: google-cloud-storage + version: 2.13.0 + manager: conda + platform: linux-64 + dependencies: + google-api-core: '>=1.31.5,<3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0' + google-auth: '>=2.23.3,<3.0dev' + google-cloud-core: '>=2.3.0,<3.0dev' + google-crc32c: '>=1.0,<2.0dev' + google-resumable-media: '>=2.6.0' + protobuf: <5.0.0dev + python: '>=3.6' + requests: '>=2.18.0,<3.0.0dev' + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-storage-2.13.0-pyhca7485f_0.conda + hash: + md5: fa7d4b2576d98b63d8ca84c76052eb95 + sha256: 8aeb7dc1298845316e9289100c5e54a9eb403c4244621d15654266c7dd225f16 + category: main + optional: false +- name: google-cloud-storage + version: 2.1.0 + manager: conda + platform: osx-arm64 + dependencies: + protobuf: '' + python: '>=3.6' + requests: '>=2.18.0,<3.0.0dev' + google-auth: '>=1.25.0,<3.0dev' + google-cloud-core: '>=1.6.0,<3.0dev' + google-api-core: '>=1.29.0,<3.0dev' + google-resumable-media: '>=1.3.0' + url: https://conda.anaconda.org/conda-forge/noarch/google-cloud-storage-2.1.0-pyh6c4a22f_0.tar.bz2 + hash: + md5: e76340074d116a15935b972757e3cd59 + sha256: 41eea7cb9adfa85e6fafd263ff6f9d8da07e237040682ab9af7adcb7e18f5f57 + category: main + optional: false +- name: google-crc32c + version: 1.1.2 + manager: conda + platform: linux-64 + dependencies: + cffi: '>=1.0.0' + libcrc32c: '>=1.1.2,<1.2.0a0' + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/google-crc32c-1.1.2-py39h328ec2c_5.conda + hash: + md5: 09f92f949dd2754de9146a31492d4edc + sha256: 21aefa9eb310072f0b2b9315db5fcc483be9a68376ceabf259095456faf7d65e + category: main + optional: false +- name: google-crc32c + version: 1.1.2 + manager: conda + platform: osx-arm64 + dependencies: + cffi: '>=1.0.0' + libcrc32c: '>=1.1.2,<1.2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/google-crc32c-1.1.2-py39hb0a979e_5.conda + hash: + md5: f7cba7a86dc980f9aa9b7ee7b0cbe7cc + sha256: 266f2e6e5ba6f3e0c8d21979a8afe8b2bebdd8784df7d4dac5ea37eb2ddecaa2 + category: main + optional: false +- name: google-pasta + version: 0.2.0 + manager: conda + platform: linux-64 + dependencies: + python: '' + six: '' + url: https://conda.anaconda.org/conda-forge/noarch/google-pasta-0.2.0-pyh8c360ce_0.tar.bz2 + hash: + md5: 26e27d7d3d7fe2336b543dd8e0f12cbf + sha256: 6fe6859982e0600bc2347df4e4ad2b374971f1b913fbae468658e40e9095e748 + category: main + optional: false +- name: google-pasta + version: 0.2.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + six: '' + url: https://conda.anaconda.org/conda-forge/noarch/google-pasta-0.2.0-pyh8c360ce_0.tar.bz2 + hash: + md5: 26e27d7d3d7fe2336b543dd8e0f12cbf + sha256: 6fe6859982e0600bc2347df4e4ad2b374971f1b913fbae468658e40e9095e748 + category: main + optional: false +- name: google-resumable-media + version: 2.6.0 + manager: conda + platform: linux-64 + dependencies: + google-crc32c: '>=1.0,<2.0.0dev' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/google-resumable-media-2.6.0-pyhd8ed1ab_0.conda + hash: + md5: 74fd9d08866e60fc412abc8dd7c5486c + sha256: 9e61d4ac7027b6447e83ab4b91fccc4baef6d1ba9490e20d06754254f7616bf5 + category: main + optional: false +- name: google-resumable-media + version: 1.3.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + six: '>=1.4.0' + google-crc32c: '>=1.0,<2.0dev' + url: https://conda.anaconda.org/conda-forge/noarch/google-resumable-media-1.3.3-pyh6c4a22f_0.tar.bz2 + hash: + md5: 4ec0a9a5d761dfe1db7032b36ffb03f2 + sha256: a151fe5a43672d74ab5ca2aa588465279bde518b0deef1d57d676be8a2e3b350 + category: main + optional: false +- name: googleapis-common-protos + version: 1.61.0 + manager: conda + platform: linux-64 + dependencies: + protobuf: '>=3.19.5,<5.0.0dev0,!=3.20.0,!=3.20.1,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/googleapis-common-protos-1.61.0-pyhd8ed1ab_0.conda + hash: + md5: f315d7fdc1905dcc2e18a1c7bed22fa9 + sha256: aa25665205e8d4895ff1bf042d2fc358a20c207271238069e13b87535f92184e + category: main + optional: false +- name: googleapis-common-protos + version: 1.61.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + protobuf: '>=3.19.5,<5.0.0dev0,!=3.20.0,!=3.20.1,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5' + url: https://conda.anaconda.org/conda-forge/noarch/googleapis-common-protos-1.61.0-pyhd8ed1ab_0.conda + hash: + md5: f315d7fdc1905dcc2e18a1c7bed22fa9 + sha256: aa25665205e8d4895ff1bf042d2fc358a20c207271238069e13b87535f92184e + category: main + optional: false +- name: graphite2 + version: 1.3.13 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=7.5.0' + libstdcxx-ng: '>=7.5.0' + url: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h58526e2_1001.tar.bz2 + hash: + md5: 8c54672728e8ec6aa6db90cf2806d220 + sha256: 65da967f3101b737b08222de6a6a14e20e480e7d523a5d1e19ace7b960b5d6b1 + category: main + optional: false +- name: graphite2 + version: 1.3.13 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=11.0.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/graphite2-1.3.13-h9f76cd9_1001.tar.bz2 + hash: + md5: 288b591645cb9cb9c0af7309ac1114f5 + sha256: 57db1e563cdfe469cd453a2988039118e96ce4b77c9219e2f1022be0e1c2b03f + category: main + optional: false +- name: graphviz + version: 9.0.0 + manager: conda + platform: linux-64 + dependencies: + cairo: '>=1.18.0,<2.0a0' + fonts-conda-ecosystem: '' + gdk-pixbuf: '>=2.42.10,<3.0a0' + gtk2: '' + gts: '>=0.7.6,<0.8.0a0' + libexpat: '>=2.5.0,<3.0a0' + libgcc-ng: '>=12' + libgd: '>=2.3.3,<2.4.0a0' + libglib: '>=2.78.1,<3.0a0' + librsvg: '>=2.56.3,<3.0a0' + libstdcxx-ng: '>=12' + libwebp-base: '>=1.3.2,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + pango: '>=1.50.14,<2.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/graphviz-9.0.0-h78e8752_1.conda + hash: + md5: a3f4cd4a512ec5db35ffbf25ba11f537 + sha256: 1813800d655c120a3941d543a6fc64e3c178c737f1c84f6b7ebe1f19f27fa4fb + category: main + optional: false +- name: graphviz + version: 9.0.0 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + cairo: '>=1.18.0,<2.0a0' + fonts-conda-ecosystem: '' + gdk-pixbuf: '>=2.42.10,<3.0a0' + gtk2: '' + gts: '>=0.7.6,<0.8.0a0' + libcxx: '>=16.0.6' + libexpat: '>=2.5.0,<3.0a0' + libgd: '>=2.3.3,<2.4.0a0' + libglib: '>=2.78.1,<3.0a0' + librsvg: '>=2.56.3,<3.0a0' + libwebp-base: '>=1.3.2,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + pango: '>=1.50.14,<2.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/graphviz-9.0.0-h3face73_1.conda + hash: + md5: 0a0e14b01da92c28f763123d146168a6 + sha256: af4c47cf50fa0b9dbe39a0dfdcd26e1b1127fcf6d3cdd37cbb860c5a276aa57e + category: main + optional: false +- name: great-expectations + version: 0.18.3 + manager: conda + platform: linux-64 + dependencies: + altair: '>=4.2.1,<5.0.0' + click: '>=7.1.2,!=8.1.4' + colorama: '>=0.4.3' + cryptography: '>=3.2' + ipython: '>=7.16.3' + ipywidgets: '>=7.5.1' + jinja2: '>=2.10' + jsonpatch: '>=1.22' + jsonschema: '>=2.5.1' + makefun: '>=1.7.0,<2' + marshmallow: '>=3.7.1,<4.0.0' + mistune: '>=0.8.4' + nbformat: '>=5.0' + notebook: '>=6.4.10' + numpy: '>=1.20.3' + packaging: '' + pandas: '>=1.1.0' + pydantic: '>=1.9.2' + pyparsing: '>=2.4' + python: '>=3.8' + python-dateutil: '>=2.8.1' + pytz: '>=2021.3' + requests: '>=2.20' + ruamel.yaml: '>=0.16,<0.17.18' + scipy: '>=1.6.0' + tqdm: '>=4.59.0' + typing-extensions: '>=3.10.0.0' + tzlocal: '>=1.2' + urllib3: '>=1.26' + url: https://conda.anaconda.org/conda-forge/noarch/great-expectations-0.18.3-pyhd8ed1ab_0.conda + hash: + md5: 365142175d8bdbe49e0d8b081d1fa992 + sha256: 3f115a9c8e9bfce9d7e638b64fa41434a2ef3eff8d0afbbe122dbd19d313926f + category: main + optional: false +- name: great-expectations + version: 0.18.3 + manager: conda + platform: osx-arm64 + dependencies: + packaging: '' + python: '>=3.8' + requests: '>=2.20' + jinja2: '>=2.10' + pandas: '>=1.1.0' + python-dateutil: '>=2.8.1' + ipywidgets: '>=7.5.1' + colorama: '>=0.4.3' + jsonschema: '>=2.5.1' + tqdm: '>=4.59.0' + tzlocal: '>=1.2' + scipy: '>=1.6.0' + jsonpatch: '>=1.22' + mistune: '>=0.8.4' + pytz: '>=2021.3' + nbformat: '>=5.0' + typing-extensions: '>=3.10.0.0' + ruamel.yaml: '>=0.16,<0.17.18' + ipython: '>=7.16.3' + cryptography: '>=3.2' + notebook: '>=6.4.10' + urllib3: '>=1.26' + pyparsing: '>=2.4' + makefun: '>=1.7.0,<2' + marshmallow: '>=3.7.1,<4.0.0' + numpy: '>=1.20.3' + altair: '>=4.2.1,<5.0.0' + click: '>=7.1.2,!=8.1.4' + pydantic: '>=1.9.2' + url: https://conda.anaconda.org/conda-forge/noarch/great-expectations-0.18.3-pyhd8ed1ab_0.conda + hash: + md5: 365142175d8bdbe49e0d8b081d1fa992 + sha256: 3f115a9c8e9bfce9d7e638b64fa41434a2ef3eff8d0afbbe122dbd19d313926f + category: main + optional: false +- name: greenlet + version: 3.0.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.0.1-py39h3d6467e_0.conda + hash: + md5: c283fa8c00251291eb7fcd9ddf7510b1 + sha256: 9bf44ce45a15f1516f9666c48a60b2a581fc8d71eb4e4b8d14b2912618ce82a9 + category: main + optional: false +- name: greenlet + version: 3.0.1 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + libcxx: '>=16.0.6' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/greenlet-3.0.1-py39h4ce5507_0.conda + hash: + md5: 6ce26219fc8abd0c4c09138e0cf4c533 + sha256: 24258971aa0619f9fd047313674b0b48f0140bad0861a8bd20ca03cc37c1c078 + category: main + optional: false +- name: grpcio + version: 1.54.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libgrpc: 1.54.3 + libstdcxx-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/grpcio-1.54.3-py39h227be39_0.conda + hash: + md5: 88730642f4e64eab737907f903d9b253 + sha256: fd1efc4fe365f429d43ee679dc7d28b7c2b5ad829a63289fccfe0c7c05e660ab + category: main + optional: false +- name: grpcio + version: 1.54.3 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + libgrpc: 1.54.3 + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/grpcio-1.54.3-py39hb198ff7_0.conda + hash: + md5: 076cb3ed6721ebab7f73670d7671f15b + sha256: 8aabc2d3baf71cde6543169ef5aa206da3120858ad5aaa1c98bb0689010bdbcb + category: main + optional: false +- name: grpcio-status + version: 1.54.2 + manager: conda + platform: linux-64 + dependencies: + googleapis-common-protos: '>=1.5.5' + grpcio: '>=1.54.2' + protobuf: '>=4.21.6' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/grpcio-status-1.54.2-pyhd8ed1ab_0.conda + hash: + md5: c7e845594733f1cb1f0f6d60a71d0dae + sha256: 8420c3da19de43e75383f3c0c93d3f556dc9b26a4bbe08f7fc557ec3c93782d4 + category: main + optional: false +- name: grpcio-status + version: 1.54.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + googleapis-common-protos: '>=1.5.5' + protobuf: '>=4.21.6' + grpcio: '>=1.54.2' + url: https://conda.anaconda.org/conda-forge/noarch/grpcio-status-1.54.2-pyhd8ed1ab_0.conda + hash: + md5: c7e845594733f1cb1f0f6d60a71d0dae + sha256: 8420c3da19de43e75383f3c0c93d3f556dc9b26a4bbe08f7fc557ec3c93782d4 + category: main + optional: false +- name: gtk2 + version: 2.24.33 + manager: conda + platform: linux-64 + dependencies: + atk-1.0: '>=2.36.0' + cairo: '>=1.16.0,<2.0.0a0' + gdk-pixbuf: '>=2.42.6,<3.0a0' + gettext: '>=0.19.8.1,<1.0a0' + libgcc-ng: '>=9.4.0' + libglib: '>=2.70.2,<3.0a0' + pango: '>=1.50.3,<1.51.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/gtk2-2.24.33-h90689f9_2.tar.bz2 + hash: + md5: 957a0255ab58aaf394a91725d73ab422 + sha256: 66d189ec36d67309fa3eb52d14d77b82359c10303c400eecc14f8eaca5939b87 + category: main + optional: false +- name: gtk2 + version: 2.24.33 + manager: conda + platform: osx-arm64 + dependencies: + atk-1.0: '>=2.36.0' + cairo: '>=1.16.0,<2.0.0a0' + gdk-pixbuf: '>=2.42.6,<3.0a0' + gettext: '>=0.19.8.1,<1.0a0' + libglib: '>=2.70.2,<3.0a0' + pango: '>=1.50.3,<1.51.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/gtk2-2.24.33-h57013de_2.tar.bz2 + hash: + md5: 144fb77338d90012ebe80d3dd13fc725 + sha256: 4bebd9809bb7e76b46af054f594eda5f280a796b7ec7f5870bd185ad5b3da338 + category: main + optional: false +- name: gts + version: 0.7.6 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libglib: '>=2.76.3,<3.0a0' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/gts-0.7.6-h977cf35_4.conda + hash: + md5: 4d8df0b0db060d33c9a702ada998a8fe + sha256: b5cd16262fefb836f69dc26d879b6508d29f8a5c5948a966c47fe99e2e19c99b + category: main + optional: false +- name: gts + version: 0.7.6 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + libglib: '>=2.76.3,<3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/gts-0.7.6-he42f4ea_4.conda + hash: + md5: 21b4dd3098f63a74cf2aa9159cbef57d + sha256: e0f8c7bc1b9ea62ded78ffa848e37771eeaaaf55b3146580513c7266862043ba + category: main + optional: false +- name: gunicorn + version: 21.2.0 + manager: conda + platform: linux-64 + dependencies: + packaging: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + setuptools: '>=3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/gunicorn-21.2.0-py39hf3d152e_1.conda + hash: + md5: a5355f72e68b8e114db59844ab5e6609 + sha256: a96b3b110bd9e8d0c3199209adf797923592f02d1869d716e320b0edc61a1785 + category: main + optional: false +- name: gunicorn + version: 21.2.0 + manager: conda + platform: osx-arm64 + dependencies: + packaging: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + setuptools: '>=3.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/gunicorn-21.2.0-py39h2804cbe_1.conda + hash: + md5: 19d282828489954a567cadf14ea35f91 + sha256: 6dbbb2958d2c369bcab4a8a52ac0734b7fce477d9ba86d623d60e34666421f6e + category: main + optional: false +- name: h5py + version: 3.10.0 + manager: conda + platform: linux-64 + dependencies: + cached-property: '' + hdf5: '>=1.14.2,<1.14.3.0a0' + libgcc-ng: '>=12' + numpy: '>=1.22.4,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/h5py-3.10.0-nompi_py39h87cadad_100.conda + hash: + md5: 37f9ca3e6e80a9e7a4cecccfbe420918 + sha256: 01a94238e74a6191516c3bee69f59f118166ff2b33a7df3a48543ea9da0c7e26 + category: main + optional: false +- name: h5py + version: 3.10.0 + manager: conda + platform: osx-arm64 + dependencies: + cached-property: '' + hdf5: '>=1.14.2,<1.14.3.0a0' + numpy: '>=1.22.4,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/h5py-3.10.0-nompi_py39haa70198_100.conda + hash: + md5: ddff96f63bf07d1328d43a2c9798f67b + sha256: 4adbdf9dabb6dbc071aea085085ebfc4b01c500545acf0d30fd54025dbdbb84a + category: main + optional: false +- name: harfbuzz + version: 8.3.0 + manager: conda + platform: linux-64 + dependencies: + cairo: '>=1.18.0,<2.0a0' + freetype: '>=2.12.1,<3.0a0' + graphite2: '' + icu: '>=73.2,<74.0a0' + libgcc-ng: '>=12' + libglib: '>=2.78.1,<3.0a0' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-8.3.0-h3d44ed6_0.conda + hash: + md5: 5a6f6c00ef982a9bc83558d9ac8f64a0 + sha256: 4b55aea03b18a4084b750eee531ad978d4a3690f63019132c26c6ad26bbe3aed + category: main + optional: false +- name: harfbuzz + version: 8.3.0 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + cairo: '>=1.18.0,<2.0a0' + freetype: '>=2.12.1,<3.0a0' + graphite2: '' + icu: '>=73.2,<74.0a0' + libcxx: '>=16.0.6' + libglib: '>=2.78.1,<3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/harfbuzz-8.3.0-h8f0ba13_0.conda + hash: + md5: 71e7f9ba27feae122733bb9f1bfe594c + sha256: 55e95aee9e5be7ada5a1cccedf1bb74c1362a7504cb0251fb48bcfa8bbd7cae3 + category: main + optional: false +- name: hdf4 + version: 4.2.15 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/hdf4-4.2.15-h2a13503_7.conda + hash: + md5: bd77f8da987968ec3927990495dc22e4 + sha256: 0d09b6dc1ce5c4005ae1c6a19dc10767932ef9a5e9c755cfdbb5189ac8fb0684 + category: main + optional: false +- name: hdf5 + version: 1.14.2 + manager: conda + platform: linux-64 + dependencies: + libaec: '>=1.0.6,<2.0a0' + libcurl: '>=8.2.1,<9.0a0' + libgcc-ng: '>=12' + libgfortran-ng: '' + libgfortran5: '>=12.3.0' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.2,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.2-nompi_h4f84152_100.conda + hash: + md5: 2de6a9bc8083b49f09b2f6eb28d3ba3c + sha256: f70f18291f912ba019cbb736bb87b6487021154733cd109147a6d9672790b6b8 + category: main + optional: false +- name: hdf5 + version: 1.14.2 + manager: conda + platform: osx-arm64 + dependencies: + libaec: '>=1.0.6,<2.0a0' + libcurl: '>=8.2.1,<9.0a0' + libcxx: '>=15.0.7' + libgfortran: 5.* + libgfortran5: '>=12.3.0' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.2,<4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/hdf5-1.14.2-nompi_h3aba7b3_100.conda + hash: + md5: 842c5b010b219058098ebfe5aa5891b9 + sha256: 2749910e21a7d1f88a81dc4709fc3565a4a3954eadb4409e7a5be1fc13a5b7ca + category: main + optional: false +- name: huggingface_hub + version: 0.19.4 + manager: conda + platform: linux-64 + dependencies: + filelock: '' + fsspec: '>=2023.5.0' + packaging: '>=20.9' + python: '>=3.8' + pyyaml: '>=5.1' + requests: '' + tqdm: '>=4.42.1' + typing-extensions: '>=3.7.4.3' + url: https://conda.anaconda.org/conda-forge/noarch/huggingface_hub-0.19.4-pyhd8ed1ab_0.conda + hash: + md5: 89932559fd83abbc8f081f688a2e764f + sha256: 411e21dd3d54738f16208ec408b7cd88785dc7007ab4fe8db1aaf9f342fab279 + category: main + optional: false +- name: huggingface_hub + version: 0.19.4 + manager: conda + platform: osx-arm64 + dependencies: + requests: '' + filelock: '' + python: '>=3.8' + pyyaml: '>=5.1' + packaging: '>=20.9' + typing-extensions: '>=3.7.4.3' + tqdm: '>=4.42.1' + fsspec: '>=2023.5.0' + url: https://conda.anaconda.org/conda-forge/noarch/huggingface_hub-0.19.4-pyhd8ed1ab_0.conda + hash: + md5: 89932559fd83abbc8f081f688a2e764f + sha256: 411e21dd3d54738f16208ec408b7cd88785dc7007ab4fe8db1aaf9f342fab279 + category: main + optional: false +- name: icu + version: '73.2' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda + hash: + md5: cc47e1facc155f91abd89b11e48e72ff + sha256: e12fd90ef6601da2875ebc432452590bc82a893041473bc1c13ef29001a73ea8 + category: main + optional: false +- name: icu + version: '73.2' + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/icu-73.2-hc8870d7_0.conda + hash: + md5: 8521bd47c0e11c5902535bb1a17c565f + sha256: ff9cd0c6cd1349954c801fb443c94192b637e1b414514539f3c49c56a39f51b1 + category: main + optional: false +- name: identify + version: 2.5.33 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + ukkonen: '' + url: https://conda.anaconda.org/conda-forge/noarch/identify-2.5.33-pyhd8ed1ab_0.conda + hash: + md5: 93c8f8ceb83827d88deeba796f07fba7 + sha256: ce2a64c18221af96226be23278d81f22ff9f64b3c047d8865590f6718915303f + category: main + optional: false +- name: identify + version: 2.5.33 + manager: conda + platform: osx-arm64 + dependencies: + ukkonen: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/identify-2.5.33-pyhd8ed1ab_0.conda + hash: + md5: 93c8f8ceb83827d88deeba796f07fba7 + sha256: ce2a64c18221af96226be23278d81f22ff9f64b3c047d8865590f6718915303f + category: main + optional: false +- name: idna + version: '3.6' + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/idna-3.6-pyhd8ed1ab_0.conda + hash: + md5: 1a76f09108576397c41c0b0c5bd84134 + sha256: 6ee4c986d69ce61e60a20b2459b6f2027baeba153f0a64995fd3cb47c2cc7e07 + category: main + optional: false +- name: idna + version: '3.6' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/idna-3.6-pyhd8ed1ab_0.conda + hash: + md5: 1a76f09108576397c41c0b0c5bd84134 + sha256: 6ee4c986d69ce61e60a20b2459b6f2027baeba153f0a64995fd3cb47c2cc7e07 + category: main + optional: false +- name: imagesize + version: 1.4.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.4' + url: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 7de5386c8fea29e76b303f37dde4c352 + sha256: c2bfd7043e0c4c12d8b5593de666c1e81d67b83c474a0a79282cc5c4ef845460 + category: main + optional: false +- name: imagesize + version: 1.4.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.4' + url: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 7de5386c8fea29e76b303f37dde4c352 + sha256: c2bfd7043e0c4c12d8b5593de666c1e81d67b83c474a0a79282cc5c4ef845460 + category: main + optional: false +- name: importlib-metadata + version: 6.10.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + zipp: '>=0.5' + url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-6.10.0-pyha770c72_0.conda + hash: + md5: ae2ad334f34040e147cc5824b450463b + sha256: 4b823af311e7f5093fca41ec0142d0e1ec9b3d1ee91924dc63133611bdfcaee5 + category: main + optional: false +- name: importlib-metadata + version: 6.10.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + zipp: '>=0.5' + url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-6.10.0-pyha770c72_0.conda + hash: + md5: ae2ad334f34040e147cc5824b450463b + sha256: 4b823af311e7f5093fca41ec0142d0e1ec9b3d1ee91924dc63133611bdfcaee5 + category: main + optional: false +- name: importlib-resources + version: 6.1.1 + manager: conda + platform: linux-64 + dependencies: + importlib_resources: '>=6.1.1,<6.1.2.0a0' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.1.1-pyhd8ed1ab_0.conda + hash: + md5: d04bd1b5bed9177dd7c3cef15e2b6710 + sha256: 89492a6619776e83d30fcdc6915fcb3a657cd345abcf68fdf6655540494ab0f0 + category: main + optional: false +- name: importlib-resources + version: 6.1.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + importlib_resources: '>=6.1.1,<6.1.2.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.1.1-pyhd8ed1ab_0.conda + hash: + md5: d04bd1b5bed9177dd7c3cef15e2b6710 + sha256: 89492a6619776e83d30fcdc6915fcb3a657cd345abcf68fdf6655540494ab0f0 + category: main + optional: false +- name: importlib_metadata + version: 6.10.0 + manager: conda + platform: linux-64 + dependencies: + importlib-metadata: '>=6.10.0,<6.10.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-6.10.0-hd8ed1ab_0.conda + hash: + md5: c063ddbb9908499fd4f20b31dc67065a + sha256: a3688dc4fb2ed84e4f11738375eee542800ca0bcb343cf5993f4e3e092dcc6bf + category: main + optional: false +- name: importlib_metadata + version: 6.10.0 + manager: conda + platform: osx-arm64 + dependencies: + importlib-metadata: '>=6.10.0,<6.10.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-6.10.0-hd8ed1ab_0.conda + hash: + md5: c063ddbb9908499fd4f20b31dc67065a + sha256: a3688dc4fb2ed84e4f11738375eee542800ca0bcb343cf5993f4e3e092dcc6bf + category: main + optional: false +- name: importlib_resources + version: 6.1.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + zipp: '>=3.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.1.1-pyhd8ed1ab_0.conda + hash: + md5: 3d5fa25cf42f3f32a12b2d874ace8574 + sha256: e584f9ae08fb2d242af0ce7e19e3cd2f85f362d8523119e08f99edb962db99ed + category: main + optional: false +- name: importlib_resources + version: 6.1.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + zipp: '>=3.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.1.1-pyhd8ed1ab_0.conda + hash: + md5: 3d5fa25cf42f3f32a12b2d874ace8574 + sha256: e584f9ae08fb2d242af0ce7e19e3cd2f85f362d8523119e08f99edb962db99ed + category: main + optional: false +- name: ipykernel + version: 6.26.0 + manager: conda + platform: linux-64 + dependencies: + __linux: '' + comm: '>=0.1.1' + debugpy: '>=1.6.5' + ipython: '>=7.23.1' + jupyter_client: '>=6.1.12' + jupyter_core: '>=4.12,!=5.0.*' + matplotlib-inline: '>=0.1' + nest-asyncio: '' + packaging: '' + psutil: '' + python: '>=3.8' + pyzmq: '>=20' + tornado: '>=6.1' + traitlets: '>=5.4.0' + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.26.0-pyhf8b6a83_0.conda + hash: + md5: 2307f71f5f0896d4b91b93e6b468abff + sha256: 9e647454f7572101657a07820ebed294df9a6a527b041cd5e4dd98b8aa3db625 + category: main + optional: false +- name: ipykernel + version: 6.26.0 + manager: conda + platform: osx-arm64 + dependencies: + packaging: '' + psutil: '' + nest-asyncio: '' + __osx: '' + appnope: '' + python: '>=3.8' + tornado: '>=6.1' + jupyter_client: '>=6.1.12' + ipython: '>=7.23.1' + matplotlib-inline: '>=0.1' + jupyter_core: '>=4.12,!=5.0.*' + debugpy: '>=1.6.5' + comm: '>=0.1.1' + pyzmq: '>=20' + traitlets: '>=5.4.0' + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.26.0-pyh3cd1d5f_0.conda + hash: + md5: 3c6e2148d30e6a762d8327a433ebfb5a + sha256: be9927d47fe23cc4d2a09d252e37e1e56ffb137767d2c0577ed882ead16f75fa + category: main + optional: false +- name: ipython + version: 8.18.1 + manager: conda + platform: linux-64 + dependencies: + __unix: '' + decorator: '' + exceptiongroup: '' + jedi: '>=0.16' + matplotlib-inline: '' + pexpect: '>4.3' + pickleshare: '' + prompt-toolkit: '>=3.0.41,<3.1.0' + pygments: '>=2.4.0' + python: '>=3.9' + stack_data: '' + traitlets: '>=5' + typing_extensions: '' + url: https://conda.anaconda.org/conda-forge/noarch/ipython-8.18.1-pyh707e725_3.conda + hash: + md5: 15c6f45a45f7ac27f6d60b0b084f6761 + sha256: d98d615ac8ad71de698afbc50e8269570d4b89706821c4ff3058a4ceec69bd9b + category: main + optional: false +- name: ipython + version: 8.18.1 + manager: conda + platform: osx-arm64 + dependencies: + typing_extensions: '' + __unix: '' + decorator: '' + exceptiongroup: '' + stack_data: '' + matplotlib-inline: '' + pickleshare: '' + python: '>=3.9' + pygments: '>=2.4.0' + traitlets: '>=5' + jedi: '>=0.16' + pexpect: '>4.3' + prompt-toolkit: '>=3.0.41,<3.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/ipython-8.18.1-pyh707e725_3.conda + hash: + md5: 15c6f45a45f7ac27f6d60b0b084f6761 + sha256: d98d615ac8ad71de698afbc50e8269570d4b89706821c4ff3058a4ceec69bd9b + category: main + optional: false +- name: ipywidgets + version: 8.1.1 + manager: conda + platform: linux-64 + dependencies: + comm: '>=0.1.3' + ipython: '>=6.1.0' + jupyterlab_widgets: '>=3.0.9,<3.1.0' + python: '>=3.7' + traitlets: '>=4.3.1' + widgetsnbextension: '>=4.0.9,<4.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.1-pyhd8ed1ab_0.conda + hash: + md5: 2605fae5ee27100e5f10037baebf4d41 + sha256: 8136defec115396ba992273a77f814d74eeafd9cc099f5430d109c60785a7f02 + category: main + optional: false +- name: ipywidgets + version: 8.1.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + traitlets: '>=4.3.1' + ipython: '>=6.1.0' + comm: '>=0.1.3' + jupyterlab_widgets: '>=3.0.9,<3.1.0' + widgetsnbextension: '>=4.0.9,<4.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.1-pyhd8ed1ab_0.conda + hash: + md5: 2605fae5ee27100e5f10037baebf4d41 + sha256: 8136defec115396ba992273a77f814d74eeafd9cc099f5430d109c60785a7f02 + category: main + optional: false +- name: isodate + version: 0.6.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + six: '' + url: https://conda.anaconda.org/conda-forge/noarch/isodate-0.6.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 4a62c93c1b5c0b920508ae3fd285eaf5 + sha256: af8f801e093da52a50ca0ea0510dfaf6898fea37e66d08d335e370235dede9fc + category: main + optional: false +- name: isodate + version: 0.6.1 + manager: conda + platform: osx-arm64 + dependencies: + six: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/isodate-0.6.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 4a62c93c1b5c0b920508ae3fd285eaf5 + sha256: af8f801e093da52a50ca0ea0510dfaf6898fea37e66d08d335e370235dede9fc + category: main + optional: false +- name: isoduration + version: 20.11.0 + manager: conda + platform: linux-64 + dependencies: + arrow: '>=0.15.0' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 4cb68948e0b8429534380243d063a27a + sha256: 7bb5c4d994361022f47a807b5e7d101b3dce16f7dd8a0af6ffad9f479d346493 + category: main + optional: false +- name: isoduration + version: 20.11.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + arrow: '>=0.15.0' + url: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 4cb68948e0b8429534380243d063a27a + sha256: 7bb5c4d994361022f47a807b5e7d101b3dce16f7dd8a0af6ffad9f479d346493 + category: main + optional: false +- name: itsdangerous + version: 2.1.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/itsdangerous-2.1.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 3c3de74912f11d2b590184f03c7cd09b + sha256: 31e3492686b4e92b53db9b48bc0eb03873b1caaf28629fee7d2d47627a2c56d3 + category: main + optional: false +- name: itsdangerous + version: 2.1.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/itsdangerous-2.1.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 3c3de74912f11d2b590184f03c7cd09b + sha256: 31e3492686b4e92b53db9b48bc0eb03873b1caaf28629fee7d2d47627a2c56d3 + category: main + optional: false +- name: jaraco.classes + version: 3.3.0 + manager: conda + platform: linux-64 + dependencies: + more-itertools: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jaraco.classes-3.3.0-pyhd8ed1ab_0.conda + hash: + md5: e9f79248d30e942f7c358ff21a1790f5 + sha256: 14f5240c3834e1b784dd41a5a14392d9150dff62a74ae851f73e65d2e2bbd891 + category: main + optional: false +- name: jaraco.classes + version: 3.3.0 + manager: conda + platform: osx-arm64 + dependencies: + more-itertools: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jaraco.classes-3.3.0-pyhd8ed1ab_0.conda + hash: + md5: e9f79248d30e942f7c358ff21a1790f5 + sha256: 14f5240c3834e1b784dd41a5a14392d9150dff62a74ae851f73e65d2e2bbd891 + category: main + optional: false +- name: jedi + version: 0.19.1 + manager: conda + platform: linux-64 + dependencies: + parso: '>=0.8.3,<0.9.0' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.1-pyhd8ed1ab_0.conda + hash: + md5: 81a3be0b2023e1ea8555781f0ad904a2 + sha256: 362f0936ef37dfd1eaa860190e42a6ebf8faa094eaa3be6aa4d9ace95f40047a + category: main + optional: false +- name: jedi + version: 0.19.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + parso: '>=0.8.3,<0.9.0' + url: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.1-pyhd8ed1ab_0.conda + hash: + md5: 81a3be0b2023e1ea8555781f0ad904a2 + sha256: 362f0936ef37dfd1eaa860190e42a6ebf8faa094eaa3be6aa4d9ace95f40047a + category: main + optional: false +- name: jeepney + version: 0.8.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jeepney-0.8.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 9800ad1699b42612478755a2d26c722d + sha256: 16639759b811866d63315fe1391f6fb45f5478b823972f4d3d9f0392b7dd80b8 + category: main + optional: false +- name: jinja2 + version: 3.1.2 + manager: conda + platform: linux-64 + dependencies: + markupsafe: '>=2.0' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.2-pyhd8ed1ab_1.tar.bz2 + hash: + md5: c8490ed5c70966d232fdd389d0dbed37 + sha256: b045faba7130ab263db6a8fdc96b1a3de5fcf85c4a607c5f11a49e76851500b5 + category: main + optional: false +- name: jinja2 + version: 3.1.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + markupsafe: '>=2.0' + url: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.2-pyhd8ed1ab_1.tar.bz2 + hash: + md5: c8490ed5c70966d232fdd389d0dbed37 + sha256: b045faba7130ab263db6a8fdc96b1a3de5fcf85c4a607c5f11a49e76851500b5 + category: main + optional: false +- name: jmespath + version: 1.0.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jmespath-1.0.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 2cfa3e1cf3fb51bb9b17acc5b5e9ea11 + sha256: 95ac5f9ee95fd4e34dc051746fc86016d3d4f6abefed113e2ede049d59ec2991 + category: main + optional: false +- name: jmespath + version: 1.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jmespath-1.0.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 2cfa3e1cf3fb51bb9b17acc5b5e9ea11 + sha256: 95ac5f9ee95fd4e34dc051746fc86016d3d4f6abefed113e2ede049d59ec2991 + category: main + optional: false +- name: joblib + version: 1.3.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + setuptools: '' + url: https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.2-pyhd8ed1ab_0.conda + hash: + md5: 4da50d410f553db77e62ab62ffaa1abc + sha256: 31e05d47970d956206188480b038829d24ac11fe8216409d8584d93d40233878 + category: main + optional: false +- name: joblib + version: 1.3.2 + manager: conda + platform: osx-arm64 + dependencies: + setuptools: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.2-pyhd8ed1ab_0.conda + hash: + md5: 4da50d410f553db77e62ab62ffaa1abc + sha256: 31e05d47970d956206188480b038829d24ac11fe8216409d8584d93d40233878 + category: main + optional: false +- name: json-c + version: '0.17' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/json-c-0.17-h7ab15ed_0.conda + hash: + md5: 9961b1f100c3b6852bd97c9233d06979 + sha256: 5646496ca07dfa1486d27ed07282967007811dfc63d6394652e87f94166ecae3 + category: main + optional: false +- name: json5 + version: 0.9.14 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7,<4.0' + url: https://conda.anaconda.org/conda-forge/noarch/json5-0.9.14-pyhd8ed1ab_0.conda + hash: + md5: dac1dabba2b5a9d1aee175c5fcc7b436 + sha256: 41514104208c092959bef0713cbd795e72c535f2f939b7903d8c97809f2adaa7 + category: main + optional: false +- name: json5 + version: 0.9.14 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7,<4.0' + url: https://conda.anaconda.org/conda-forge/noarch/json5-0.9.14-pyhd8ed1ab_0.conda + hash: + md5: dac1dabba2b5a9d1aee175c5fcc7b436 + sha256: 41514104208c092959bef0713cbd795e72c535f2f939b7903d8c97809f2adaa7 + category: main + optional: false +- name: jsonpatch + version: '1.33' + manager: conda + platform: linux-64 + dependencies: + jsonpointer: '>=1.9' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_0.conda + hash: + md5: bfdb7c5c6ad1077c82a69a8642c87aff + sha256: fbb17e33ace3225c6416d1604637c1058906b8223da968cc015128985336b2b4 + category: main + optional: false +- name: jsonpatch + version: '1.33' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + jsonpointer: '>=1.9' + url: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_0.conda + hash: + md5: bfdb7c5c6ad1077c82a69a8642c87aff + sha256: fbb17e33ace3225c6416d1604637c1058906b8223da968cc015128985336b2b4 + category: main + optional: false +- name: jsonpickle + version: 3.0.2 + manager: conda + platform: linux-64 + dependencies: + importlib_metadata: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jsonpickle-3.0.2-pyhd8ed1ab_1.conda + hash: + md5: f351864256e291b24b5a3bedda184bff + sha256: c947f2a64e4f06c722973894afb8e26df3aa2212e2e742def3506ccbad42141b + category: main + optional: false +- name: jsonpickle + version: 3.0.2 + manager: conda + platform: osx-arm64 + dependencies: + importlib_metadata: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jsonpickle-3.0.2-pyhd8ed1ab_1.conda + hash: + md5: f351864256e291b24b5a3bedda184bff + sha256: c947f2a64e4f06c722973894afb8e26df3aa2212e2e742def3506ccbad42141b + category: main + optional: false +- name: jsonpointer + version: '2.4' + manager: conda + platform: linux-64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-2.4-py39hf3d152e_3.conda + hash: + md5: 23255e64bc45e9bc0b7d87c108357ce6 + sha256: cd6f07324a83678072675e8c0720558c807682466181f33eb4d2de03aa8bff49 + category: main + optional: false +- name: jsonpointer + version: '2.4' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/jsonpointer-2.4-py39h2804cbe_3.conda + hash: + md5: 522964a5f0d509502fed024f31b5f5cd + sha256: ca4f1e2aa60e48ab5e64c82e19b1c53642c114766f04c69d095ee05dcf012c19 + category: main + optional: false +- name: jsonschema + version: 4.20.0 + manager: conda + platform: linux-64 + dependencies: + attrs: '>=22.2.0' + importlib_resources: '>=1.4.0' + jsonschema-specifications: '>=2023.03.6' + pkgutil-resolve-name: '>=1.3.10' + python: '>=3.8' + referencing: '>=0.28.4' + rpds-py: '>=0.7.1' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.20.0-pyhd8ed1ab_0.conda + hash: + md5: 1116d79def5268414fb0917520b2bbf1 + sha256: 77aae609097d06deedb8ef8407a44b23d5fef95962ba6fe1c959ac7bd6195296 + category: main + optional: false +- name: jsonschema + version: 4.20.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + attrs: '>=22.2.0' + importlib_resources: '>=1.4.0' + pkgutil-resolve-name: '>=1.3.10' + jsonschema-specifications: '>=2023.03.6' + referencing: '>=0.28.4' + rpds-py: '>=0.7.1' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.20.0-pyhd8ed1ab_0.conda + hash: + md5: 1116d79def5268414fb0917520b2bbf1 + sha256: 77aae609097d06deedb8ef8407a44b23d5fef95962ba6fe1c959ac7bd6195296 + category: main + optional: false +- name: jsonschema-specifications + version: 2023.11.2 + manager: conda + platform: linux-64 + dependencies: + importlib_resources: '>=1.4.0' + python: '>=3.8' + referencing: '>=0.31.0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.11.2-pyhd8ed1ab_0.conda + hash: + md5: 73884ca36d6d96cbce498cde99fab40f + sha256: e26115d02dc208a05b557c8dd670923270803b9b3b8af4e22b93d659d1ec77ec + category: main + optional: false +- name: jsonschema-specifications + version: 2023.11.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + importlib_resources: '>=1.4.0' + referencing: '>=0.31.0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.11.2-pyhd8ed1ab_0.conda + hash: + md5: 73884ca36d6d96cbce498cde99fab40f + sha256: e26115d02dc208a05b557c8dd670923270803b9b3b8af4e22b93d659d1ec77ec + category: main + optional: false +- name: jsonschema-with-format-nongpl + version: 4.20.0 + manager: conda + platform: linux-64 + dependencies: + fqdn: '' + idna: '' + isoduration: '' + jsonpointer: '>1.13' + jsonschema: '>=4.20.0,<4.20.1.0a0' + python: '' + rfc3339-validator: '' + rfc3986-validator: '>0.1.0' + uri-template: '' + webcolors: '>=1.11' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.20.0-pyhd8ed1ab_0.conda + hash: + md5: a168c5f84010711f6d4ae650bc22b480 + sha256: 03558b25daa57137fdf98e92731ba50ff5506f265294ac2eef5ec465c76ecf57 + category: main + optional: false +- name: jsonschema-with-format-nongpl + version: 4.20.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + idna: '' + rfc3339-validator: '' + uri-template: '' + fqdn: '' + isoduration: '' + jsonpointer: '>1.13' + webcolors: '>=1.11' + rfc3986-validator: '>0.1.0' + jsonschema: '>=4.20.0,<4.20.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.20.0-pyhd8ed1ab_0.conda + hash: + md5: a168c5f84010711f6d4ae650bc22b480 + sha256: 03558b25daa57137fdf98e92731ba50ff5506f265294ac2eef5ec465c76ecf57 + category: main + optional: false +- name: jupyter + version: 1.0.0 + manager: conda + platform: linux-64 + dependencies: + ipykernel: '' + ipywidgets: '' + jupyter_console: '' + nbconvert: '' + notebook: '' + python: '>=3.6' + qtconsole-base: '' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter-1.0.0-pyhd8ed1ab_10.conda + hash: + md5: 056b8cc3d9b03f54fc49e6d70d7dc359 + sha256: 308b521b149e7a1739f717538b929bc2d87b9001b94f13ee8baa939632a86150 + category: main + optional: false +- name: jupyter + version: 1.0.0 + manager: conda + platform: osx-arm64 + dependencies: + ipywidgets: '' + notebook: '' + nbconvert: '' + ipykernel: '' + qtconsole-base: '' + jupyter_console: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter-1.0.0-pyhd8ed1ab_10.conda + hash: + md5: 056b8cc3d9b03f54fc49e6d70d7dc359 + sha256: 308b521b149e7a1739f717538b929bc2d87b9001b94f13ee8baa939632a86150 + category: main + optional: false +- name: jupyter-cache + version: 0.6.1 + manager: conda + platform: linux-64 + dependencies: + attrs: '' + click: '' + importlib-metadata: '' + nbclient: '>=0.2,<0.8' + nbformat: '' + python: '>=3.8' + pyyaml: '' + sqlalchemy: '>=1.3.12,<3' + tabulate: '' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter-cache-0.6.1-pyhd8ed1ab_0.conda + hash: + md5: 2e360820ae68e3d28e1a5a9d2714ca5c + sha256: b22ba507904f33fcc7b218cc2a3ed8d39027524d0f223f3696b8344b7c5a1e1f + category: main + optional: false +- name: jupyter-cache + version: 0.6.1 + manager: conda + platform: osx-arm64 + dependencies: + pyyaml: '' + click: '' + importlib-metadata: '' + tabulate: '' + nbformat: '' + attrs: '' + python: '>=3.8' + sqlalchemy: '>=1.3.12,<3' + nbclient: '>=0.2,<0.8' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter-cache-0.6.1-pyhd8ed1ab_0.conda + hash: + md5: 2e360820ae68e3d28e1a5a9d2714ca5c + sha256: b22ba507904f33fcc7b218cc2a3ed8d39027524d0f223f3696b8344b7c5a1e1f + category: main + optional: false +- name: jupyter-lsp + version: 2.2.1 + manager: conda + platform: linux-64 + dependencies: + importlib-metadata: '>=4.8.3' + jupyter_server: '>=1.1.2' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.1-pyhd8ed1ab_0.conda + hash: + md5: d1a5efc65bfabc3bfebf4d3a204da897 + sha256: 0f995f60609fb50db74bed3637165ad202cf091ec0804519c11b6cffce901e88 + category: main + optional: false +- name: jupyter-lsp + version: 2.2.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + importlib-metadata: '>=4.8.3' + jupyter_server: '>=1.1.2' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.1-pyhd8ed1ab_0.conda + hash: + md5: d1a5efc65bfabc3bfebf4d3a204da897 + sha256: 0f995f60609fb50db74bed3637165ad202cf091ec0804519c11b6cffce901e88 + category: main + optional: false +- name: jupyter_client + version: 8.6.0 + manager: conda + platform: linux-64 + dependencies: + importlib_metadata: '>=4.8.3' + jupyter_core: '>=4.12,!=5.0.*' + python: '>=3.8' + python-dateutil: '>=2.8.2' + pyzmq: '>=23.0' + tornado: '>=6.2' + traitlets: '>=5.3' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.0-pyhd8ed1ab_0.conda + hash: + md5: 6bd3f1069cdebb44c7ae9efb900e312d + sha256: 86cbb9070862cf23a245451efce539ca214e610849d0950bb8ac90c545bd158d + category: main + optional: false +- name: jupyter_client + version: 8.6.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + python-dateutil: '>=2.8.2' + jupyter_core: '>=4.12,!=5.0.*' + traitlets: '>=5.3' + importlib_metadata: '>=4.8.3' + pyzmq: '>=23.0' + tornado: '>=6.2' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.0-pyhd8ed1ab_0.conda + hash: + md5: 6bd3f1069cdebb44c7ae9efb900e312d + sha256: 86cbb9070862cf23a245451efce539ca214e610849d0950bb8ac90c545bd158d + category: main + optional: false +- name: jupyter_console + version: 6.6.3 + manager: conda + platform: linux-64 + dependencies: + ipykernel: '>=6.14' + ipython: '' + jupyter_client: '>=7.0.0' + jupyter_core: '>=4.12,!=5.0.*' + prompt_toolkit: '>=3.0.30' + pygments: '' + python: '>=3.7' + pyzmq: '>=17' + traitlets: '>=5.4' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_0.conda + hash: + md5: 7cf6f52a66f8e3cd9d8b6c231262dcab + sha256: 4e51764d5fe2f6e43d83bcfbcf8b4da6569721bf82eaf4d647be8717cd6be75a + category: main + optional: false +- name: jupyter_console + version: 6.6.3 + manager: conda + platform: osx-arm64 + dependencies: + ipython: '' + pygments: '' + python: '>=3.7' + pyzmq: '>=17' + jupyter_core: '>=4.12,!=5.0.*' + jupyter_client: '>=7.0.0' + ipykernel: '>=6.14' + traitlets: '>=5.4' + prompt_toolkit: '>=3.0.30' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_0.conda + hash: + md5: 7cf6f52a66f8e3cd9d8b6c231262dcab + sha256: 4e51764d5fe2f6e43d83bcfbcf8b4da6569721bf82eaf4d647be8717cd6be75a + category: main + optional: false +- name: jupyter_core + version: 5.5.0 + manager: conda + platform: linux-64 + dependencies: + platformdirs: '>=2.5' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + traitlets: '>=5.3' + url: https://conda.anaconda.org/conda-forge/linux-64/jupyter_core-5.5.0-py39hf3d152e_0.conda + hash: + md5: 87274099cd45c591edd6ed59bcc96095 + sha256: 23e7d01036b8c25bb054b28e4ee299a2cac7ae62af672bdda5f814c7b6ff470d + category: main + optional: false +- name: jupyter_core + version: 5.5.0 + manager: conda + platform: osx-arm64 + dependencies: + platformdirs: '>=2.5' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + traitlets: '>=5.3' + url: https://conda.anaconda.org/conda-forge/osx-arm64/jupyter_core-5.5.0-py39h2804cbe_0.conda + hash: + md5: 42a8bd9a68a56049e0e4b29209c48c6d + sha256: 71c4ff910e60afa6a336e7d3b6d9332e615411e1810197d9076629314c208999 + category: main + optional: false +- name: jupyter_events + version: 0.9.0 + manager: conda + platform: linux-64 + dependencies: + jsonschema-with-format-nongpl: '>=4.18.0' + python: '>=3.8' + python-json-logger: '>=2.0.4' + pyyaml: '>=5.3' + referencing: '' + rfc3339-validator: '' + rfc3986-validator: '>=0.1.1' + traitlets: '>=5.3' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.9.0-pyhd8ed1ab_0.conda + hash: + md5: 00ba25993f0dba38cf72a7224e33289f + sha256: 713f0cc927a862862a6d35bfb29c4114f987e4f59e2a8a14f71f23fcd7edfec3 + category: main + optional: false +- name: jupyter_events + version: 0.9.0 + manager: conda + platform: osx-arm64 + dependencies: + rfc3339-validator: '' + referencing: '' + python: '>=3.8' + pyyaml: '>=5.3' + rfc3986-validator: '>=0.1.1' + traitlets: '>=5.3' + python-json-logger: '>=2.0.4' + jsonschema-with-format-nongpl: '>=4.18.0' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.9.0-pyhd8ed1ab_0.conda + hash: + md5: 00ba25993f0dba38cf72a7224e33289f + sha256: 713f0cc927a862862a6d35bfb29c4114f987e4f59e2a8a14f71f23fcd7edfec3 + category: main + optional: false +- name: jupyter_server + version: 2.12.1 + manager: conda + platform: linux-64 + dependencies: + anyio: '>=3.1.0' + argon2-cffi: '' + jinja2: '' + jupyter_client: '>=7.4.4' + jupyter_core: '>=4.12,!=5.0.*' + jupyter_events: '>=0.9.0' + jupyter_server_terminals: '' + nbconvert-core: '>=6.4.4' + nbformat: '>=5.3.0' + overrides: '' + packaging: '' + prometheus_client: '' + python: '>=3.8' + pyzmq: '>=24' + send2trash: '>=1.8.2' + terminado: '>=0.8.3' + tornado: '>=6.2.0' + traitlets: '>=5.6.0' + websocket-client: '' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.12.1-pyhd8ed1ab_0.conda + hash: + md5: e9781be1e6c93b5df2c180a9f9242420 + sha256: c4aabe2041afb8fde1f049549c2e292265612d07dd4d1156f3e183ba6a6f007b + category: main + optional: false +- name: jupyter_server + version: 2.12.1 + manager: conda + platform: osx-arm64 + dependencies: + packaging: '' + jinja2: '' + prometheus_client: '' + websocket-client: '' + argon2-cffi: '' + overrides: '' + jupyter_server_terminals: '' + python: '>=3.8' + terminado: '>=0.8.3' + jupyter_core: '>=4.12,!=5.0.*' + nbconvert-core: '>=6.4.4' + tornado: '>=6.2.0' + jupyter_client: '>=7.4.4' + nbformat: '>=5.3.0' + pyzmq: '>=24' + traitlets: '>=5.6.0' + anyio: '>=3.1.0' + send2trash: '>=1.8.2' + jupyter_events: '>=0.9.0' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.12.1-pyhd8ed1ab_0.conda + hash: + md5: e9781be1e6c93b5df2c180a9f9242420 + sha256: c4aabe2041afb8fde1f049549c2e292265612d07dd4d1156f3e183ba6a6f007b + category: main + optional: false +- name: jupyter_server_terminals + version: 0.4.4 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + terminado: '>=0.8.3' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.4.4-pyhd8ed1ab_1.conda + hash: + md5: 7c0965e1d4a0ee1529e8eaa03a78a5b3 + sha256: 9f4c5fef9beef9fceed628db7a10b888f3308b37ae257ad3d50046088317ebf1 + category: main + optional: false +- name: jupyter_server_terminals + version: 0.4.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + terminado: '>=0.8.3' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.4.4-pyhd8ed1ab_1.conda + hash: + md5: 7c0965e1d4a0ee1529e8eaa03a78a5b3 + sha256: 9f4c5fef9beef9fceed628db7a10b888f3308b37ae257ad3d50046088317ebf1 + category: main + optional: false +- name: jupyterlab + version: 4.0.9 + manager: conda + platform: linux-64 + dependencies: + async-lru: '>=1.0.0' + importlib_metadata: '>=4.8.3' + importlib_resources: '>=1.4' + ipykernel: '' + jinja2: '>=3.0.3' + jupyter-lsp: '>=2.0.0' + jupyter_core: '' + jupyter_server: '>=2.4.0,<3' + jupyterlab_server: '>=2.19.0,<3' + notebook-shim: '>=0.2' + packaging: '' + python: '>=3.8' + tomli: '' + tornado: '>=6.2.0' + traitlets: '' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.0.9-pyhd8ed1ab_0.conda + hash: + md5: 7da6e874b0904e411ec2fd8e6082841e + sha256: 1c55e63e4b84810796c8827370ebd597ad3f45bcd0c1fa9975a363bc6a895f23 + category: main + optional: false +- name: jupyterlab + version: 4.0.9 + manager: conda + platform: osx-arm64 + dependencies: + packaging: '' + traitlets: '' + tomli: '' + ipykernel: '' + jupyter_core: '' + python: '>=3.8' + tornado: '>=6.2.0' + jinja2: '>=3.0.3' + importlib_metadata: '>=4.8.3' + jupyter_server: '>=2.4.0,<3' + importlib_resources: '>=1.4' + jupyter-lsp: '>=2.0.0' + async-lru: '>=1.0.0' + jupyterlab_server: '>=2.19.0,<3' + notebook-shim: '>=0.2' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.0.9-pyhd8ed1ab_0.conda + hash: + md5: 7da6e874b0904e411ec2fd8e6082841e + sha256: 1c55e63e4b84810796c8827370ebd597ad3f45bcd0c1fa9975a363bc6a895f23 + category: main + optional: false +- name: jupyterlab_pygments + version: 0.3.0 + manager: conda + platform: linux-64 + dependencies: + pygments: '>=2.4.1,<3' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_0.conda + hash: + md5: 3f0915b1fb2252ab73686a533c5f9d3f + sha256: 6ee596138a778a841261476408435da78e3000661f3ee025fb6c3ed17d28c8b3 + category: main + optional: false +- name: jupyterlab_pygments + version: 0.3.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + pygments: '>=2.4.1,<3' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_0.conda + hash: + md5: 3f0915b1fb2252ab73686a533c5f9d3f + sha256: 6ee596138a778a841261476408435da78e3000661f3ee025fb6c3ed17d28c8b3 + category: main + optional: false +- name: jupyterlab_server + version: 2.25.2 + manager: conda + platform: linux-64 + dependencies: + 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.8' + requests: '>=2.31' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.25.2-pyhd8ed1ab_0.conda + hash: + md5: f45557d5551b54dc2a74133a310bc1ba + sha256: 51c13a87072a64df1a0ae14fbb470bc4e36becf4d50693ffab53174199ca4f4b + category: main + optional: false +- name: jupyterlab_server + version: 2.25.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + packaging: '>=21.3' + jinja2: '>=3.0.3' + importlib-metadata: '>=4.8.3' + jupyter_server: '>=1.21,<3' + babel: '>=2.10' + json5: '>=0.9.0' + requests: '>=2.31' + jsonschema: '>=4.18' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.25.2-pyhd8ed1ab_0.conda + hash: + md5: f45557d5551b54dc2a74133a310bc1ba + sha256: 51c13a87072a64df1a0ae14fbb470bc4e36becf4d50693ffab53174199ca4f4b + category: main + optional: false +- name: jupyterlab_widgets + version: 3.0.9 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.9-pyhd8ed1ab_0.conda + hash: + md5: 8370e0a9dc443f9b45a23fd30e7a6b3b + sha256: ec66991d2175f7b1f35973d6c4f56ad9a49666f77acf1037d72f3bc6e37224f3 + category: main + optional: false +- name: jupyterlab_widgets + version: 3.0.9 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.9-pyhd8ed1ab_0.conda + hash: + md5: 8370e0a9dc443f9b45a23fd30e7a6b3b + sha256: ec66991d2175f7b1f35973d6c4f56ad9a49666f77acf1037d72f3bc6e37224f3 + category: main + optional: false +- name: jupytext + version: 1.16.0 + manager: conda + platform: linux-64 + dependencies: + markdown-it-py: '>=1.0' + mdit-py-plugins: '' + nbformat: '' + packaging: '' + python: '>=3.8' + pyyaml: '' + toml: '' + url: https://conda.anaconda.org/conda-forge/noarch/jupytext-1.16.0-pyhd8ed1ab_0.conda + hash: + md5: 562071ea5a2172022aadf6c3ddbf22eb + sha256: 9050a4c3ef58c61e0f6f8fff270b8c20617a35a4d14f651cc76af52665563a4a + category: main + optional: false +- name: jupytext + version: 1.16.0 + manager: conda + platform: osx-arm64 + dependencies: + pyyaml: '' + packaging: '' + toml: '' + nbformat: '' + mdit-py-plugins: '' + python: '>=3.8' + markdown-it-py: '>=1.0' + url: https://conda.anaconda.org/conda-forge/noarch/jupytext-1.16.0-pyhd8ed1ab_0.conda + hash: + md5: 562071ea5a2172022aadf6c3ddbf22eb + sha256: 9050a4c3ef58c61e0f6f8fff270b8c20617a35a4d14f651cc76af52665563a4a + category: main + optional: false +- name: kealib + version: 1.5.2 + manager: conda + platform: linux-64 + dependencies: + hdf5: '>=1.14.2,<1.14.3.0a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/kealib-1.5.2-hcd42e92_1.conda + hash: + md5: b04c039f0bd511533a0d8bc8a7b6835e + sha256: 1278aaba7bfd9a143a58a2d5e13296702b6bd77f7b43f6ecace555a55579bdad + category: main + optional: false +- name: keras + version: 2.14.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/keras-2.14.0-pyhd8ed1ab_0.conda + hash: + md5: 1f549fcd82b651b879789fd922e32e1f + sha256: 1e45448fd8da68a5cc27e6a8f01e0bddbefbe3e33cb638fd3a65149b64c69393 + category: main + optional: false +- name: keras + version: 2.14.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/keras-2.14.0-pyhd8ed1ab_0.conda + hash: + md5: 1f549fcd82b651b879789fd922e32e1f + sha256: 1e45448fd8da68a5cc27e6a8f01e0bddbefbe3e33cb638fd3a65149b64c69393 + category: main + optional: false +- name: keyring + version: 24.3.0 + manager: conda + platform: linux-64 + dependencies: + importlib_metadata: '>=4.11.4' + jaraco.classes: '' + jeepney: '>=0.4.2' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + secretstorage: '>=3.2' + url: https://conda.anaconda.org/conda-forge/linux-64/keyring-24.3.0-py39hf3d152e_0.conda + hash: + md5: 1426c4f9994cb7e55859b44b98bc7b3e + sha256: a7538a914feb54dc3e7ee46431af5f0a40e668b29224998e6d3be044a1a7606e + category: main + optional: false +- name: keyring + version: 24.3.0 + manager: conda + platform: osx-arm64 + dependencies: + importlib_metadata: '>=4.11.4' + jaraco.classes: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/keyring-24.3.0-py39h2804cbe_0.conda + hash: + md5: 20cfef7aef2c344c6136baec5495cf1c + sha256: 68b8474cab4f80f1e287399f85736f09b724d41d972257a61f7c96a4ded266fe + category: main + optional: false +- name: keyutils + version: 1.6.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=10.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 + hash: + md5: 30186d27e2c9fa62b45fb1476b7200e3 + sha256: 150c05a6e538610ca7c43beb3a40d65c90537497a4f6a5f4d15ec0451b6f5ebb + category: main + optional: false +- name: kiwisolver + version: 1.4.5 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.5-py39h7633fee_1.conda + hash: + md5: c9f74d717e5a2847a9f8b779c54130f2 + sha256: 620d2aa2c3f016aa569b4a679688cb34f27c05e08555e4860099cf001bd740e4 + category: main + optional: false +- name: kiwisolver + version: 1.4.5 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.5-py39hbd775c9_1.conda + hash: + md5: 6a5917bf932fcaae394baaf72cc11edb + sha256: ef29cfa7a05431f89f0bcf456d2d094dc3ff3cdbfebf7210a1fd55755ef61926 + category: main + optional: false +- name: krb5 + version: 1.21.2 + manager: conda + platform: linux-64 + dependencies: + keyutils: '>=1.6.1,<2.0a0' + libedit: '>=3.1.20191231,<4.0a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + openssl: '>=3.1.2,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.2-h659d440_0.conda + hash: + md5: cd95826dbd331ed1be26bdf401432844 + sha256: 259bfaae731989b252b7d2228c1330ef91b641c9d68ff87dae02cbae682cb3e4 + category: main + optional: false +- name: krb5 + version: 1.21.2 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + libedit: '>=3.1.20191231,<4.0a0' + openssl: '>=3.1.2,<4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.2-h92f50d5_0.conda + hash: + md5: 92f1cff174a538e0722bf2efb16fc0b2 + sha256: 70bdb9b4589ec7c7d440e485ae22b5a352335ffeb91a771d4c162996c3070875 + category: main + optional: false +- name: kubernetes + version: 1.25.3 + manager: conda + platform: linux-64 + dependencies: + kubernetes-client: 1.25.3 + kubernetes-node: 1.25.3 + kubernetes-server: 1.25.3 + url: https://conda.anaconda.org/conda-forge/linux-64/kubernetes-1.25.3-ha770c72_0.conda + hash: + md5: d9c3df17c3020b839d47f252ba6885fd + sha256: 624ee9537664756032437b6378497b9cbd90d9a6bbca6e805615615314a6d480 + category: main + optional: false +- name: kubernetes + version: 1.25.3 + manager: conda + platform: osx-arm64 + dependencies: + kubernetes-client: 1.25.3 + kubernetes-node: 1.25.3 + kubernetes-server: 1.25.3 + url: https://conda.anaconda.org/conda-forge/osx-arm64/kubernetes-1.25.3-hce30654_0.conda + hash: + md5: 813fd5d1d2285f73e19ba2b88361ed88 + sha256: aca8453c92756205810500b60a25b71bb8b2a8dd5efaa5afe3e32c5ede727ff2 + category: main + optional: false +- name: kubernetes-client + version: 1.25.3 + manager: conda + platform: linux-64 + dependencies: + __glibc: '>=2.17' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/kubernetes-client-1.25.3-h449c3f6_0.conda + hash: + md5: 53a9490aea421c6b43605c17b3fbb26c + sha256: b6baddbf7fe6e53e71cf8998d225fa8e6d187b60dc0e466d34fbfe876aec9a5c + category: main + optional: false +- name: kubernetes-client + version: 1.25.3 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/kubernetes-client-1.25.3-hc52dabb_0.conda + hash: + md5: a96c1ce6bfbfa86db064d2bc9ead119e + sha256: 6bca1eda3def0f5323569451d6b700ea1253017cc4970f3c3a063ae718006b93 + category: main + optional: false +- name: kubernetes-node + version: 1.25.3 + manager: conda + platform: linux-64 + dependencies: + __glibc: '>=2.17' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/kubernetes-node-1.25.3-h449c3f6_0.conda + hash: + md5: f706346637b6175a91d7fc3b5c04db16 + sha256: 9be6b6d2fc4fc90741e2efb12a7e3b60f3bb44e6c458ef6e6fe8824635020c87 + category: main + optional: false +- name: kubernetes-node + version: 1.25.3 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/kubernetes-node-1.25.3-hc52dabb_0.conda + hash: + md5: 6695a06c4a0aa24d5a30a5d399a4f5b0 + sha256: d2656858f31486c4658bc842d7104da8cd68ec204c213b5b2a4e23ff25a65c2d + category: main + optional: false +- name: kubernetes-server + version: 1.25.3 + manager: conda + platform: linux-64 + dependencies: + __glibc: '>=2.17' + kubernetes-node: 1.25.3 + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/kubernetes-server-1.25.3-h449c3f6_0.conda + hash: + md5: c7df8e51b39ffb41d2f3c9a3c782ef6d + sha256: 3b8410040ff355d871ce90bcbccc6fba8482d097411da99a73d7bfb7e13bf264 + category: main + optional: false +- name: kubernetes-server + version: 1.25.3 + manager: conda + platform: osx-arm64 + dependencies: + kubernetes-node: 1.25.3 + url: https://conda.anaconda.org/conda-forge/osx-arm64/kubernetes-server-1.25.3-hc52dabb_0.conda + hash: + md5: fe30b91760c813b6083a0285787b1ca4 + sha256: dcef741d5f7d922b8b7490057e8532214197489dead2de22dee136055d8705ee + category: main + optional: false +- name: lcms2 + version: '2.16' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.16-hb7c19ff_0.conda + hash: + md5: 51bb7010fc86f70eee639b4bb7a894f5 + sha256: 5c878d104b461b7ef922abe6320711c0d01772f4cd55de18b674f88547870041 + category: main + optional: false +- name: lcms2 + version: '2.16' + manager: conda + platform: osx-arm64 + dependencies: + libjpeg-turbo: '>=3.0.0,<4.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.16-ha0e7c42_0.conda + hash: + md5: 66f6c134e76fe13cce8a9ea5814b5dd5 + sha256: 151e0c84feb7e0747fabcc85006b8973b22f5abbc3af76a9add0b0ef0320ebe4 + category: main + optional: false +- name: ld_impl_linux-64 + version: '2.40' + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h41732ed_0.conda + hash: + md5: 7aca3059a1729aa76c597603f10b0dd3 + sha256: f6cc89d887555912d6c61b295d398cff9ec982a3417d38025c45d5dd9b9e79cd + category: main + optional: false +- name: lerc + version: 4.0.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h27087fc_0.tar.bz2 + hash: + md5: 76bbff344f0134279f225174e9064c8f + sha256: cb55f36dcd898203927133280ae1dc643368af041a48bcf7c026acb7c47b0c12 + category: main + optional: false +- name: lerc + version: 4.0.0 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=13.0.1' + url: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-h9a09cb3_0.tar.bz2 + hash: + md5: de462d5aacda3b30721b512c5da4e742 + sha256: 6f068bb53dfb6147d3147d981bb851bb5477e769407ad4e6a68edf482fdcb958 + category: main + optional: false +- name: libabseil + version: '20230125.3' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h59595ed_0.conda + hash: + md5: d1db1b8be7c3a8983dcbbbfe4f0765de + sha256: 3c6fab31ed4dc8428605588454596b307b1bd59d33b0c7073c407ab51408b011 + category: main + optional: false +- name: libabseil + version: '20230125.3' + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20230125.3-cxx17_h13dd4ca_0.conda + hash: + md5: e9edfc273c30153b3427332e90110422 + sha256: dacf281442b411eb4a4dece69618c247dbaacaa71669ca6631fc924be86ceab8 + category: main + optional: false +- name: libaec + version: 1.1.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.2-h59595ed_1.conda + hash: + md5: 127b0be54c1c90760d7fe02ea7a56426 + sha256: fdde15e74dc099ab1083823ec0f615958e53d9a8fae10405af977de251668bea + category: main + optional: false +- name: libaec + version: 1.1.2 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libaec-1.1.2-h13dd4ca_1.conda + hash: + md5: b7962cdc2cedcc9f8d12928824c11fbd + sha256: c9d6f01d511bd3686ce590addf829f34031b95e3feb34418496cbb45924c5d17 + category: main + optional: false +- name: libarchive + version: 3.7.2 + manager: conda + platform: linux-64 + dependencies: + bzip2: '>=1.0.8,<2.0a0' + libgcc-ng: '>=12' + libxml2: '>=2.11.5,<2.12.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + lz4-c: '>=1.9.3,<1.10.0a0' + lzo: '>=2.10,<3.0a0' + openssl: '>=3.1.2,<4.0a0' + xz: '>=5.2.6,<6.0a0' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.2-h039dbb9_0.conda + hash: + md5: 611d6c83d1130ea60c916531adfb11db + sha256: b82b9f4a1515877ea65416bf7fd9cc77cae77d7b5977eada2b999ee525a0d5c9 + category: main + optional: false +- name: libarrow + version: 12.0.1 + manager: conda + platform: linux-64 + dependencies: + aws-crt-cpp: '>=0.21.0,<0.21.1.0a0' + aws-sdk-cpp: '>=1.10.57,<1.10.58.0a0' + bzip2: '>=1.0.8,<2.0a0' + glog: '>=0.6.0,<0.7.0a0' + libabseil: '>=20230125.3,<20230126.0a0' + libbrotlidec: '>=1.0.9,<1.1.0a0' + libbrotlienc: '>=1.0.9,<1.1.0a0' + libgcc-ng: '>=12' + libgoogle-cloud: '>=2.12.0,<2.13.0a0' + libgrpc: '>=1.54.3,<1.55.0a0' + libprotobuf: '>=3.21.12,<3.22.0a0' + libstdcxx-ng: '>=12' + libthrift: '>=0.18.1,<0.18.2.0a0' + libutf8proc: '>=2.8.0,<3.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + lz4-c: '>=1.9.3,<1.10.0a0' + openssl: '>=3.1.2,<4.0a0' + orc: '>=1.9.0,<1.9.1.0a0' + re2: '>=2023.3.2,<2023.3.3.0a0' + snappy: '>=1.1.10,<2.0a0' + ucx: '>=1.14.0,<1.15.0a0' + zstd: '>=1.5.2,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.1-hb87d912_8_cpu.conda + hash: + md5: 3f3b11398fe79b578e3c44dd00a44e4a + sha256: 046cc9a10999c58d351e3778ba7de5f694f90f46384726f26e6ab0e2826ccff7 + category: main + optional: false +- name: libarrow + version: 12.0.1 + manager: conda + platform: osx-arm64 + dependencies: + aws-crt-cpp: '>=0.21.0,<0.21.1.0a0' + aws-sdk-cpp: '>=1.10.57,<1.10.58.0a0' + bzip2: '>=1.0.8,<2.0a0' + glog: '>=0.6.0,<0.7.0a0' + libabseil: '>=20230125.3,<20230126.0a0' + libbrotlidec: '>=1.0.9,<1.1.0a0' + libbrotlienc: '>=1.0.9,<1.1.0a0' + libcxx: '>=15.0.7' + libgoogle-cloud: '>=2.12.0,<2.13.0a0' + libgrpc: '>=1.54.3,<1.55.0a0' + libprotobuf: '>=3.21.12,<3.22.0a0' + libthrift: '>=0.18.1,<0.18.2.0a0' + libutf8proc: '>=2.8.0,<3.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + lz4-c: '>=1.9.3,<1.10.0a0' + openssl: '>=3.1.2,<4.0a0' + orc: '>=1.9.0,<1.9.1.0a0' + re2: '>=2023.3.2,<2023.3.3.0a0' + snappy: '>=1.1.10,<2.0a0' + zstd: '>=1.5.2,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-12.0.1-h0b136c2_8_cpu.conda + hash: + md5: bfd29a8b76d92468d98d473f4d587796 + sha256: 7852b48ec223c71371f4dac033e5823c64c80bf887a432cdddfafe9a6c91dfce + category: main + optional: false +- name: libblas + version: 3.9.0 + manager: conda + platform: linux-64 + dependencies: + libopenblas: '>=0.3.25,<1.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda + hash: + md5: 2b7bb4f7562c8cf334fc2e20c2d28abc + sha256: 8a0ee1de693a9b3da4a11b95ec81b40dd434bd01fa1f5f38f8268cd2146bf8f0 + category: main + optional: false +- name: libblas + version: 3.9.0 + manager: conda + platform: osx-arm64 + dependencies: + libopenblas: '>=0.3.25,<1.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-20_osxarm64_openblas.conda + hash: + md5: 49bc8dec26663241ee064b2d7116ec2d + sha256: 5b5b8394352c8ca06b15dcc9319d0af3e9f1dc03fc0a6f6deef05d664d6b763a + category: main + optional: false +- name: libboost-headers + version: 1.83.0 + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/linux-64/libboost-headers-1.83.0-ha770c72_0.conda + hash: + md5: 1fc57b3ba24d18cc75f431d7feb2c785 + sha256: aaa194e8b7ba401e6507a2f6dc0714d2f8f5a9951f8be18b96c250b0a1175982 + category: main + optional: false +- name: libbrotlicommon + version: 1.0.9 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.0.9-h166bdaf_9.conda + hash: + md5: 61641e239f96eae2b8492dc7e755828c + sha256: fc57c0876695c5b4ab7173438580c1d7eaa7dccaf14cb6467ca9e0e97abe0cf0 + category: main + optional: false +- name: libbrotlicommon + version: 1.0.9 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.0.9-h1a8c8d9_9.conda + hash: + md5: 82354022c67480c61419b6e47377af89 + sha256: 53f4a6cc4f5795adf33fda00b86a0e91513c534ae44859754e9c07954d3a7148 + category: main + optional: false +- name: libbrotlidec + version: 1.0.9 + manager: conda + platform: linux-64 + dependencies: + libbrotlicommon: 1.0.9 + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.0.9-h166bdaf_9.conda + hash: + md5: 081aa22f4581c08e4372b0b6c2f8478e + sha256: 564f301430c3c61bc5e149e74157ec181ed2a758befc89f7c38466d515a0f614 + category: main + optional: false +- name: libbrotlidec + version: 1.0.9 + manager: conda + platform: osx-arm64 + dependencies: + libbrotlicommon: 1.0.9 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.0.9-h1a8c8d9_9.conda + hash: + md5: af03c66e8cb688221bdc9e2b0faaa2bf + sha256: 2de613dcccbbe40f90a256784ab23f7292aaa0985642ca35496cb9c177d8220b + category: main + optional: false +- name: libbrotlienc + version: 1.0.9 + manager: conda + platform: linux-64 + dependencies: + libbrotlicommon: 1.0.9 + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.conda + hash: + md5: 1f0a03af852a9659ed2bf08f2f1704fd + sha256: d27bc2562ea3f3b2bfd777f074f1cac6bfa4a737233dad288cd87c4634a9bb3a + category: main + optional: false +- name: libbrotlienc + version: 1.0.9 + manager: conda + platform: osx-arm64 + dependencies: + libbrotlicommon: 1.0.9 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.0.9-h1a8c8d9_9.conda + hash: + md5: 8231f81e72b1113eb2ed8d2586c82691 + sha256: 37e766c0b87d06637bdfc68e072c227ce2dac82b81d26b5f9ac57fb948e2e2b7 + category: main + optional: false +- name: libcblas + version: 3.9.0 + manager: conda + platform: linux-64 + dependencies: + libblas: 3.9.0 + url: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda + hash: + md5: 36d486d72ab64ffea932329a1d3729a3 + sha256: 0e34fb0f82262f02fcb279ab4a1db8d50875dc98e3019452f8f387e6bf3c0247 + category: main + optional: false +- name: libcblas + version: 3.9.0 + manager: conda + platform: osx-arm64 + dependencies: + libblas: 3.9.0 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-20_osxarm64_openblas.conda + hash: + md5: 89f4718753c08afe8cda4dd5791ba94c + sha256: d3a74638f60e034202e373cf2950c69a8d831190d497881d13cbf789434d2489 + category: main + optional: false +- name: libcrc32c + version: 1.1.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.4.0' + libstdcxx-ng: '>=9.4.0' + url: https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2 + hash: + md5: c965a5aa0d5c1c37ffc62dff36e28400 + sha256: fd1d153962764433fe6233f34a72cdeed5dcf8a883a85769e8295ce940b5b0c5 + category: main + optional: false +- name: libcrc32c + version: 1.1.2 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=11.1.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libcrc32c-1.1.2-hbdafb3b_0.tar.bz2 + hash: + md5: 32bd82a6a625ea6ce090a81c3d34edeb + sha256: 58477b67cc719060b5b069ba57161e20ba69b8695d154a719cb4b60caf577929 + category: main + optional: false +- name: libcst + version: 1.1.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + pyyaml: '>=5.2' + typing_extensions: '>=3.7.4.2' + typing_inspect: '>=0.4.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libcst-1.1.0-py39h73dd9e7_0.conda + hash: + md5: 941f293c813dfc0196b5ab89fb85d31c + sha256: 5d9f148d71b568dfe1230541a27cece168d8fdc81d4a42e8008c076e1cb96f05 + category: main + optional: false +- name: libcurl + version: 8.4.0 + manager: conda + platform: linux-64 + dependencies: + krb5: '>=1.21.2,<1.22.0a0' + libgcc-ng: '>=12' + libnghttp2: '>=1.52.0,<2.0a0' + libssh2: '>=1.11.0,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.3,<4.0a0' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.4.0-hca28451_0.conda + hash: + md5: 1158ac1d2613b28685644931f11ee807 + sha256: 25f4b6a8827d7b17a66e0bd9b5d194bf9a9e4a46fb14e2ef472fdad4b39426a6 + category: main + optional: false +- name: libcurl + version: 8.5.0 + manager: conda + platform: osx-arm64 + dependencies: + krb5: '>=1.21.2,<1.22.0a0' + libnghttp2: '>=1.58.0,<2.0a0' + libssh2: '>=1.11.0,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.2.0,<4.0a0' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.5.0-h2d989ff_0.conda + hash: + md5: f1211ed00947a84e15a964a8f459f620 + sha256: f1c04be217aaf161ce3c99a8d618871295b5dc1eae2f7ff7b32078af50303f5b + category: main + optional: false +- name: libcxx + version: 16.0.6 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-16.0.6-h4653b0c_0.conda + hash: + md5: 9d7d724faf0413bf1dbc5a85935700c8 + sha256: 11d3fb51c14832d9e4f6d84080a375dec21ea8a3a381a1910e67ff9cedc20355 + category: main + optional: false +- name: libdeflate + version: '1.19' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.19-hd590300_0.conda + hash: + md5: 1635570038840ee3f9c71d22aa5b8b6d + sha256: 985ad27aa0ba7aad82afa88a8ede6a1aacb0aaca950d710f15d85360451e72fd + category: main + optional: false +- name: libdeflate + version: '1.19' + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.19-hb547adb_0.conda + hash: + md5: f8c1eb0e99e90b55965c6558578537cc + sha256: 6a3d188a6ae845a742dc85c5fb3f7eb1e252726cd74f0b8a7fa25ec09db6b87a + category: main + optional: false +- name: libedit + version: 3.1.20191231 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=7.5.0' + ncurses: '>=6.2,<7.0.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2 + hash: + md5: 4d331e44109e3f0e19b4cb8f9b82f3e1 + sha256: a57d37c236d8f7c886e01656f4949d9dcca131d2a0728609c6f7fa338b65f1cf + category: main + optional: false +- name: libedit + version: 3.1.20191231 + manager: conda + platform: osx-arm64 + dependencies: + ncurses: '>=6.2,<7.0.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20191231-hc8eb9b7_2.tar.bz2 + hash: + md5: 30e4362988a2623e9eb34337b83e01f9 + sha256: 3912636197933ecfe4692634119e8644904b41a58f30cad9d1fc02f6ba4d9fca + category: main + optional: false +- name: libev + version: '4.33' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=7.5.0' + url: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-h516909a_1.tar.bz2 + hash: + md5: 6f8720dff19e17ce5d48cfe7f3d2f0a3 + sha256: 8c9635aa0ea28922877dc96358f9547f6a55fc7e2eb75a556b05f1725496baf9 + category: main + optional: false +- name: libev + version: '4.33' + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h642e427_1.tar.bz2 + hash: + md5: 566dbf70fe79eacdb3c3d3d195a27f55 + sha256: eb7325eb2e6bd4c291cb9682781b35b8c0f68cb72651c35a5b9dd22707ebd25c + category: main + optional: false +- name: libevent + version: 2.1.12 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + openssl: '>=3.1.1,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda + hash: + md5: a1cfcc585f0c42bf8d5546bb1dfb668d + sha256: 2e14399d81fb348e9d231a82ca4d816bf855206923759b69ad006ba482764131 + category: main + optional: false +- name: libevent + version: 2.1.12 + manager: conda + platform: osx-arm64 + dependencies: + openssl: '>=3.1.1,<4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libevent-2.1.12-h2757513_1.conda + hash: + md5: 1a109764bff3bdc7bdd84088347d71dc + sha256: 8c136d7586259bb5c0d2b913aaadc5b9737787ae4f40e3ad1beaf96c80b919b7 + category: main + optional: false +- name: libexpat + version: 2.5.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.5.0-hcb278e6_1.conda + hash: + md5: 6305a3dd2752c76335295da4e581f2fd + sha256: 74c98a563777ae2ad71f1f74d458a8ab043cee4a513467c159ccf159d0e461f3 + category: main + optional: false +- name: libexpat + version: 2.5.0 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.5.0-hb7217d7_1.conda + hash: + md5: 5a097ad3d17e42c148c9566280481317 + sha256: 7d143a9c991579ad4207f84c632650a571c66329090daa32b3c87cf7311c3381 + category: main + optional: false +- name: libffi + version: 3.4.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.4.0' + url: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 + hash: + md5: d645c6d2ac96843a2bfaccd2d62b3ac3 + sha256: ab6e9856c21709b7b517e940ae7028ae0737546122f83c2aa5d692860c3b149e + category: main + optional: false +- name: libffi + version: 3.4.2 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2 + hash: + md5: 086914b672be056eb70fd4285b6783b6 + sha256: 41b3d13efb775e340e4dba549ab5c029611ea6918703096b2eaa9c015c0750ca + category: main + optional: false +- name: libgcc-ng + version: 13.2.0 + manager: conda + platform: linux-64 + dependencies: + _libgcc_mutex: '0.1' + _openmp_mutex: '>=4.5' + url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h807b86a_3.conda + hash: + md5: 23fdf1fef05baeb7eadc2aed5fb0011f + sha256: 5e88f658e07a30ab41b154b42c59f079b168acfa9551a75bdc972099453f4105 + category: main + optional: false +- name: libgd + version: 2.3.3 + manager: conda + platform: linux-64 + dependencies: + expat: '' + fontconfig: '>=2.14.2,<3.0a0' + fonts-conda-ecosystem: '' + freetype: '>=2.12.1,<3.0a0' + icu: '>=73.2,<74.0a0' + libexpat: '>=2.5.0,<3.0a0' + libgcc-ng: '>=12' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + libwebp: '' + libwebp-base: '>=1.3.2,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + zlib: '' + url: https://conda.anaconda.org/conda-forge/linux-64/libgd-2.3.3-h119a65a_9.conda + hash: + md5: cfebc557e54905dadc355c0e9f003004 + sha256: b74f95a6e1f3b31a74741b39cba83ed99fc82d17243c0fd3b5ab16ddd48ab89d + category: main + optional: false +- name: libgd + version: 2.3.3 + manager: conda + platform: osx-arm64 + dependencies: + expat: '' + fontconfig: '>=2.14.2,<3.0a0' + fonts-conda-ecosystem: '' + freetype: '>=2.12.1,<3.0a0' + icu: '>=73.2,<74.0a0' + libexpat: '>=2.5.0,<3.0a0' + libiconv: '>=1.17,<2.0a0' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + libwebp: '' + libwebp-base: '>=1.3.2,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + zlib: '' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libgd-2.3.3-hfdf3952_9.conda + hash: + md5: 0d847466f115fbdaaf2b6926f2e33278 + sha256: cfdecfaa27807abc2728bd8c60b923ce1b44020553e122e9a56fc3acb77acaec + category: main + optional: false +- name: libgdal + version: 3.8.0 + manager: conda + platform: linux-64 + dependencies: + __glibc: '>=2.17,<3.0.a0' + blosc: '>=1.21.5,<2.0a0' + cfitsio: '>=4.3.0,<4.3.1.0a0' + freexl: '>=2.0.0,<3.0a0' + geos: '>=3.12.1,<3.12.2.0a0' + geotiff: '>=1.7.1,<1.8.0a0' + giflib: '>=5.2.1,<5.3.0a0' + hdf4: '>=4.2.15,<4.2.16.0a0' + hdf5: '>=1.14.2,<1.14.3.0a0' + json-c: '>=0.17,<0.18.0a0' + kealib: '>=1.5.2,<1.6.0a0' + lerc: '>=4.0.0,<5.0a0' + libaec: '>=1.1.2,<2.0a0' + libarchive: '>=3.7.2,<3.8.0a0' + libcurl: '>=8.4.0,<9.0a0' + libdeflate: '>=1.19,<1.20.0a0' + libexpat: '>=2.5.0,<3.0a0' + libgcc-ng: '>=12' + libiconv: '>=1.17,<2.0a0' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libkml: '>=1.3.0,<1.4.0a0' + libnetcdf: '>=4.9.2,<4.9.3.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libpq: '>=16.1,<17.0a0' + libspatialite: '>=5.1.0,<5.2.0a0' + libsqlite: '>=3.44.1,<4.0a0' + libstdcxx-ng: '>=12' + libtiff: '>=4.6.0,<4.7.0a0' + libuuid: '>=2.38.1,<3.0a0' + libwebp-base: '>=1.3.2,<2.0a0' + libxml2: '>=2.11.6,<2.12.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + lz4-c: '>=1.9.3,<1.10.0a0' + openjpeg: '>=2.5.0,<3.0a0' + openssl: '>=3.1.4,<4.0a0' + pcre2: '>=10.42,<10.43.0a0' + poppler: '>=23.11.0,<23.12.0a0' + postgresql: '' + proj: '>=9.3.0,<9.3.1.0a0' + tiledb: '>=2.16,<2.17.0a0' + xerces-c: '>=3.2.4,<3.3.0a0' + xz: '>=5.2.6,<6.0a0' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libgdal-3.8.0-he7dcfe9_6.conda + hash: + md5: 16ff703a847430fa074c5d53916740c1 + sha256: 06ccb879fc2783c371f1b02d062c4e90dfe4d8c5e9f2f83213bbef0fe27a00b0 + category: main + optional: false +- name: libgfortran + version: 5.0.0 + manager: conda + platform: osx-arm64 + dependencies: + libgfortran5: 13.2.0 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-5.0.0-13_2_0_hd922786_1.conda + hash: + md5: 1ad37a5c60c250bb2b4a9f75563e181c + sha256: bc8750e7893e693fa380bf2f342d4a5ce44995467cbdf72e56a00e5106b4892d + category: main + optional: false +- name: libgfortran-ng + version: 13.2.0 + manager: conda + platform: linux-64 + dependencies: + libgfortran5: 13.2.0 + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_3.conda + hash: + md5: 73031c79546ad06f1fe62e57fdd021bc + sha256: 5b918950b84605b6865de438757f507b1eff73c96fd562f7022c80028b088c14 + category: main + optional: false +- name: libgfortran5 + version: 13.2.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=13.2.0' + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-ha4646dd_3.conda + hash: + md5: c714d905cdfa0e70200f68b80cc04764 + sha256: 0084a1d29a4f8ee3b8edad80eb6c42e5f0480f054f28cf713fb314bebb347a50 + category: main + optional: false +- name: libgfortran5 + version: 13.2.0 + manager: conda + platform: osx-arm64 + dependencies: + llvm-openmp: '>=8.0.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-13.2.0-hf226fd6_1.conda + hash: + md5: 4480d71b98c87faafab132d33e23135e + sha256: cb9cb11e49a6a8466ea7556a723080d3aeefd556df9b444b941afc5b54368b22 + category: main + optional: false +- name: libglib + version: 2.78.2 + manager: conda + platform: linux-64 + dependencies: + gettext: '>=0.21.1,<1.0a0' + libffi: '>=3.4,<4.0a0' + libgcc-ng: '>=12' + libiconv: '>=1.17,<2.0a0' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + pcre2: '>=10.42,<10.43.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.78.2-h783c2da_0.conda + hash: + md5: a69b70cf435577750468d02cbd596094 + sha256: 66a5dd5e9c13431d0d23324e2d4dd0ad189f6fe003b51bc8880ceeb3f6460f93 + category: main + optional: false +- name: libglib + version: 2.78.2 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + gettext: '>=0.21.1,<1.0a0' + libcxx: '>=16.0.6' + libffi: '>=3.4,<4.0a0' + libiconv: '>=1.17,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + pcre2: '>=10.42,<10.43.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.78.2-hb438215_0.conda + hash: + md5: a2334b9d0b7b79c7d674ede8e21149b7 + sha256: 8c7ba8a886cbf5a8c91a814179463389e0bcaa9a7cf831f0cf849b6e4216cdc5 + category: main + optional: false +- name: libgoogle-cloud + version: 2.12.0 + manager: conda + platform: linux-64 + dependencies: + libabseil: '>=20230125.3,<20230126.0a0' + libcrc32c: '>=1.1.2,<1.2.0a0' + libcurl: '>=8.1.2,<9.0a0' + libgcc-ng: '>=12' + libgrpc: '>=1.54.2,<1.55.0a0' + libprotobuf: '>=3.21.12,<3.22.0a0' + libstdcxx-ng: '>=12' + openssl: '>=3.1.1,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda + hash: + md5: 0dee716254497604762957076ac76540 + sha256: d133fdd36924ac5068ebfec493ec6a888aeb328060b4bc1c1928340047ebce26 + category: main + optional: false +- name: libgoogle-cloud + version: 2.12.0 + manager: conda + platform: osx-arm64 + dependencies: + libabseil: '>=20230125.3,<20230126.0a0' + libcrc32c: '>=1.1.2,<1.2.0a0' + libcurl: '>=8.1.2,<9.0a0' + libcxx: '>=15.0.7' + libgrpc: '>=1.54.2,<1.55.0a0' + libprotobuf: '>=3.21.12,<3.22.0a0' + openssl: '>=3.1.1,<4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-2.12.0-he22f4c0_1.conda + hash: + md5: 0f0853e2cdd835d56c6e2d3e78e08692 + sha256: bbf6428fdc0428ba01f88b9ef3af75bab31e17eae113bc235615e70151940a40 + category: main + optional: false +- name: libgrpc + version: 1.54.3 + manager: conda + platform: linux-64 + dependencies: + c-ares: '>=1.19.1,<2.0a0' + libabseil: '>=20230125.3,<20230126.0a0' + libgcc-ng: '>=12' + libprotobuf: '>=3.21.12,<3.22.0a0' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.1,<4.0a0' + re2: '>=2023.3.2,<2023.3.3.0a0' + zlib: '' + url: https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda + hash: + md5: 7af7c59ab24db007dfd82e0a3a343f66 + sha256: f5fea0c2eececb010529ac5863fbede05a2413ea8dc1a1c419db861f68ed66d7 + category: main + optional: false +- name: libgrpc + version: 1.54.3 + manager: conda + platform: osx-arm64 + dependencies: + c-ares: '>=1.19.1,<2.0a0' + libabseil: '>=20230125.3,<20230126.0a0' + libcxx: '>=15.0.7' + libprotobuf: '>=3.21.12,<3.22.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.1,<4.0a0' + re2: '>=2023.3.2,<2023.3.3.0a0' + zlib: '' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libgrpc-1.54.3-h0a338ca_0.conda + hash: + md5: 181d9f230758e567c2a5c947ecc5c813 + sha256: 8340196ab92b0e4ca136d0ab9278e96caf8594c5065ef33dc9f5c3a4e659521d + category: main + optional: false +- name: libhwloc + version: 2.9.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + libxml2: '>=2.11.5,<2.12.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.9.3-default_h554bfaf_1009.conda + hash: + md5: f36ddc11ca46958197a45effdd286e45 + sha256: 6950fee24766d03406e0f6f965262a5d98829c71eed8d1004f313892423b559b + category: main + optional: false +- name: libiconv + version: '1.17' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=10.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-h166bdaf_0.tar.bz2 + hash: + md5: b62b52da46c39ee2bc3c162ac7f1804d + sha256: 6a81ebac9f1aacdf2b4f945c87ad62b972f0f69c8e0981d68e111739e6720fd7 + category: main + optional: false +- name: libiconv + version: '1.17' + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.17-he4db4b2_0.tar.bz2 + hash: + md5: 686f9c755574aa221f29fbcf36a67265 + sha256: 2eb33065783b802f71d52bef6f15ce0fafea0adc8506f10ebd0d490244087bec + category: main + optional: false +- name: libjpeg-turbo + version: 3.0.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.0.0-hd590300_1.conda + hash: + md5: ea25936bb4080d843790b586850f82b8 + sha256: b954e09b7e49c2f2433d6f3bb73868eda5e378278b0f8c1dd10a7ef090e14f2f + category: main + optional: false +- name: libjpeg-turbo + version: 3.0.0 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.0.0-hb547adb_1.conda + hash: + md5: 3ff1e053dc3a2b8e36b9bfa4256a58d1 + sha256: a42054eaa38e84fc1e5ab443facac4bbc9d1b6b6f23f54b7bf4f1eb687e1d993 + category: main + optional: false +- name: libkml + version: 1.3.0 + manager: conda + platform: linux-64 + dependencies: + libboost-headers: '' + libexpat: '>=2.5.0,<3.0a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + uriparser: '>=0.9.7,<1.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libkml-1.3.0-h01aab08_1018.conda + hash: + md5: 3eb5f16bcc8a02892199aa63555c731f + sha256: f67fc0be886c7eac14dbce858bfcffbc90a55b598e897e513f0979dd2caad750 + category: main + optional: false +- name: liblapack + version: 3.9.0 + manager: conda + platform: linux-64 + dependencies: + libblas: 3.9.0 + url: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda + hash: + md5: 6fabc51f5e647d09cc010c40061557e0 + sha256: ad7745b8d0f2ccb9c3ba7aaa7167d62fc9f02e45eb67172ae5f0dfb5a3b1a2cc + category: main + optional: false +- name: liblapack + version: 3.9.0 + manager: conda + platform: osx-arm64 + dependencies: + libblas: 3.9.0 + url: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-20_osxarm64_openblas.conda + hash: + md5: 1fefac78f2315455ce2d7f34782eac0a + sha256: e13f79828a7752f6e0a74cbe62df80c551285f6c37de86bc3bd9987c97faca57 + category: main + optional: false +- name: libnetcdf + version: 4.9.2 + manager: conda + platform: linux-64 + dependencies: + blosc: '>=1.21.4,<2.0a0' + bzip2: '>=1.0.8,<2.0a0' + hdf4: '>=4.2.15,<4.2.16.0a0' + hdf5: '>=1.14.2,<1.14.3.0a0' + libaec: '>=1.0.6,<2.0a0' + libcurl: '>=8.2.1,<9.0a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + libxml2: '>=2.11.5,<2.12.0a0' + libzip: '>=1.10.1,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.2,<4.0a0' + zlib: '' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h80fb2b6_112.conda + hash: + md5: a19fa6cacf80c8a366572853d5890eb4 + sha256: 305ffc3ecaffce10754e4d057daa9803e8dc86d68b14524a791c7dc5598c1d2f + category: main + optional: false +- name: libnghttp2 + version: 1.58.0 + manager: conda + platform: linux-64 + dependencies: + c-ares: '>=1.21.0,<2.0a0' + libev: '>=4.33,<4.34.0a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.4,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.58.0-h47da74e_0.conda + hash: + md5: 9b13d5ee90fc9f09d54fd403247342b4 + sha256: 151b18e4f92dcca263a6d23e4beb0c4e2287aa1c7d0587ff71ef50035ed34aca + category: main + optional: false +- name: libnghttp2 + version: 1.58.0 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + c-ares: '>=1.21.0,<2.0a0' + libcxx: '>=16.0.6' + libev: '>=4.33,<4.34.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.4,<4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.58.0-ha4dd798_0.conda + hash: + md5: b93d94874cfd44bc96496c2ee69f82a9 + sha256: 3597032667444f91ae59343c553da6e93f2b3359bc2c0dd6b7f8260e41572e9c + category: main + optional: false +- name: libnsl + version: 2.0.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda + hash: + md5: 30fd6e37fe21f86f4bd26d6ee73eeec7 + sha256: 26d77a3bb4dceeedc2a41bd688564fe71bf2d149fdcf117049970bc02ff1add6 + category: main + optional: false +- name: libnuma + version: 2.0.16 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.16-h0b41bf4_1.conda + hash: + md5: 28bfe2cb11357ccc5be21101a6b7ce86 + sha256: 814a50cba215548ec3ebfb53033ffb9b3b070b2966570ff44910b8d9ba1c359d + category: main + optional: false +- name: libopenblas + version: 0.3.25 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libgfortran-ng: '' + libgfortran5: '>=12.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda + hash: + md5: d172b34a443b95f86089e8229ddc9a17 + sha256: 628564517895ee1b09cf72c817548bd80ef1acce6a8214a8520d9f7b44c4cfaf + category: main + optional: false +- name: libopenblas + version: 0.3.25 + manager: conda + platform: osx-arm64 + dependencies: + libgfortran: 5.* + libgfortran5: '>=12.3.0' + llvm-openmp: '>=16.0.6' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.25-openmp_h6c19121_0.conda + hash: + md5: a1843550403212b9dedeeb31466ade03 + sha256: b112e0d500bc0314ea8d393efac3ab8c67857e5a2b345348c98e703ee92723e5 + category: main + optional: false +- name: libpng + version: 1.6.39 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.39-h753d276_0.conda + hash: + md5: e1c890aebdebbfbf87e2c917187b4416 + sha256: a32b36d34e4f2490b99bddbc77d01a674d304f667f0e62c89e02c961addef462 + category: main + optional: false +- name: libpng + version: 1.6.39 + manager: conda + platform: osx-arm64 + dependencies: + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.39-h76d750c_0.conda + hash: + md5: 0078e6327c13cfdeae6ff7601e360383 + sha256: 21ab8409a8e66f9408b96428c0a36a9768faee9fe623c56614576f9e12962981 + category: main + optional: false +- name: libpq + version: '16.1' + manager: conda + platform: linux-64 + dependencies: + krb5: '>=1.21.2,<1.22.0a0' + libgcc-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.4,<3.2.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libpq-16.1-hfc447b1_0.conda + hash: + md5: 2b7f1893cf40b4ccdc0230bcd94d5ed9 + sha256: 8c92a8cce329a83cc9e94b19d18200c661957c00cfb464f26237d24730864585 + category: main + optional: false +- name: libpq + version: '16.1' + manager: conda + platform: osx-arm64 + dependencies: + krb5: '>=1.21.2,<1.22.0a0' + libxml2: '>=2.12.2,<2.13.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.2.0,<4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libpq-16.1-h9aca644_6.conda + hash: + md5: 6bd9c3d66b05a49340797131b9cd1fad + sha256: 82782215135744329919e77b20bbfbb38a19ccde27bbad121def3b203e4f8ed1 + category: main + optional: false +- name: libprotobuf + version: 3.21.12 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda + hash: + md5: e3a7d4ba09b8dc939b98fef55f539220 + sha256: 2df8888c51c23dedc831ba4378bad259e95c3a20a6408f54926a6a6f629f6153 + category: main + optional: false +- name: libprotobuf + version: 3.21.12 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-3.21.12-ha614eb4_2.conda + hash: + md5: 440548f3f8e573a427553ee877c5f6c3 + sha256: 3910b38529c44119a293fccc93021cab6fe73ebbdaa8194dcf43a711a433bc55 + category: main + optional: false +- name: librsvg + version: 2.56.3 + manager: conda + platform: linux-64 + dependencies: + cairo: '>=1.16.0,<2.0a0' + gdk-pixbuf: '>=2.42.10,<3.0a0' + gettext: '>=0.21.1,<1.0a0' + libgcc-ng: '>=12' + libglib: '>=2.76.4,<3.0a0' + libxml2: '>=2.11.4,<2.12.0a0' + pango: '>=1.50.14,<2.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.56.3-h98fae49_0.conda + hash: + md5: 620e754f4344f4c27259ff460a2b9c50 + sha256: 4b2dd7745caadc425045dbe31a2300b3b8de4346873f04aa9b552c56f3b1e001 + category: main + optional: false +- name: librsvg + version: 2.56.3 + manager: conda + platform: osx-arm64 + dependencies: + cairo: '>=1.18.0,<2.0a0' + gdk-pixbuf: '>=2.42.10,<3.0a0' + gettext: '>=0.21.1,<1.0a0' + libglib: '>=2.78.1,<3.0a0' + libxml2: '>=2.12.1,<2.13.0a0' + pango: '>=1.50.14,<2.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/librsvg-2.56.3-h55a2576_1.conda + hash: + md5: d9624ec11650aa93e0b2c2612c3548f5 + sha256: 59043f2536d61a32378553c4fa7f56e97bca12165c37a45de9e7439a06f5ac16 + category: main + optional: false +- name: librttopo + version: 1.1.0 + manager: conda + platform: linux-64 + dependencies: + geos: '>=3.12.1,<3.12.2.0a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/librttopo-1.1.0-h8917695_15.conda + hash: + md5: 20c3c14bc491f30daecaa6f73e2223ae + sha256: 03e248787162a1804683c614c0681c2488fa6d9f353cb32e2f8c1158157165ea + category: main + optional: false +- name: libsodium + version: 1.0.18 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=7.5.0' + url: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.18-h36c2ea0_1.tar.bz2 + hash: + md5: c3788462a6fbddafdb413a9f9053e58d + sha256: 53da0c8b79659df7b53eebdb80783503ce72fb4b10ed6e9e05cc0e9e4207a130 + category: main + optional: false +- name: libsodium + version: 1.0.18 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.18-h27ca646_1.tar.bz2 + hash: + md5: 90859688dbca4735b74c02af14c4c793 + sha256: 1d95fe5e5e6a0700669aab454b2a32f97289c9ed8d1f7667c2ba98327a6f05bc + category: main + optional: false +- name: libspatialindex + version: 1.9.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.3.0' + libstdcxx-ng: '>=9.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-1.9.3-h9c3ff4c_4.tar.bz2 + hash: + md5: d87fbe9c0ff589e802ff13872980bfd9 + sha256: 588fbd0c11bc44e354365d5f836183216a4ed17d680b565ff416a93b839f1a8b + category: main + optional: false +- name: libspatialite + version: 5.1.0 + manager: conda + platform: linux-64 + dependencies: + freexl: '>=2.0.0,<3.0a0' + geos: '>=3.12.1,<3.12.2.0a0' + libgcc-ng: '>=12' + librttopo: '>=1.1.0,<1.2.0a0' + libsqlite: '>=3.44.1,<4.0a0' + libstdcxx-ng: '>=12' + libxml2: '>=2.11.6,<2.12.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + proj: '>=9.3.0,<9.3.1.0a0' + sqlite: '' + zlib: '' + url: https://conda.anaconda.org/conda-forge/linux-64/libspatialite-5.1.0-h7385560_2.conda + hash: + md5: 4260750b280f6f7c38a4459bf0d919ff + sha256: 5efbd5bc05ebaa6bb66b7e408d2998a4116029c2e3c2b0336e29267488d93a45 + category: main + optional: false +- name: libsqlite + version: 3.44.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.44.2-h2797004_0.conda + hash: + md5: 3b6a9f225c3dbe0d24f4fedd4625c5bf + sha256: ee2c4d724a3ed60d5b458864d66122fb84c6ce1df62f735f90d8db17b66cd88a + category: main + optional: false +- name: libsqlite + version: 3.44.2 + manager: conda + platform: osx-arm64 + dependencies: + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.44.2-h091b4b1_0.conda + hash: + md5: d7e1af696cfadec251a0abdd7b79ed77 + sha256: f0dc2fe69eddb4bab72ff6bb0da51d689294f466ee1b01e80ced1e7878a21aa5 + category: main + optional: false +- name: libssh2 + version: 1.11.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.1,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda + hash: + md5: 1f5a58e686b13bcfde88b93f547d23fe + sha256: 50e47fd9c4f7bf841a11647ae7486f65220cfc988ec422a4475fe8d5a823824d + category: main + optional: false +- name: libssh2 + version: 1.11.0 + manager: conda + platform: osx-arm64 + dependencies: + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.1,<4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.0-h7a5bd25_0.conda + hash: + md5: 029f7dc931a3b626b94823bc77830b01 + sha256: bb57d0c53289721fff1eeb3103a1c6a988178e88d8a8f4345b0b91a35f0e0015 + category: main + optional: false +- name: libstdcxx-ng + version: 13.2.0 + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-h7e041cc_3.conda + hash: + md5: 937eaed008f6bf2191c5fe76f87755e9 + sha256: 6c6c49efedcc5709a66f19fb6b26b69c6a5245310fd1d9a901fd5e38aaf7f882 + category: main + optional: false +- name: libthrift + version: 0.18.1 + manager: conda + platform: linux-64 + dependencies: + libevent: '>=2.1.12,<2.1.13.0a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.1,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.18.1-h8fd135c_2.conda + hash: + md5: bbf65f7688512872f063810623b755dc + sha256: 06cd0ccd95d19389d0b0146402ac5536e4bb0abd08a88650f95dd18debd62677 + category: main + optional: false +- name: libthrift + version: 0.18.1 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + libevent: '>=2.1.12,<2.1.13.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.1,<4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libthrift-0.18.1-ha061701_2.conda + hash: + md5: c1a4bb91d705cc903de58a95aa35ab5b + sha256: 4b3cbe168c7fb070a79960fd20bdc60b309d79805619ed93cdf93f71bdc88bf6 + category: main + optional: false +- name: libtiff + version: 4.6.0 + manager: conda + platform: linux-64 + dependencies: + lerc: '>=4.0.0,<5.0a0' + libdeflate: '>=1.19,<1.20.0a0' + libgcc-ng: '>=12' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libstdcxx-ng: '>=12' + libwebp-base: '>=1.3.2,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + xz: '>=5.2.6,<6.0a0' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-ha9c0a0a_2.conda + hash: + md5: 55ed21669b2015f77c180feb1dd41930 + sha256: 45158f5fbee7ee3e257e6b9f51b9f1c919ed5518a94a9973fe7fa4764330473e + category: main + optional: false +- name: libtiff + version: 4.6.0 + manager: conda + platform: osx-arm64 + dependencies: + lerc: '>=4.0.0,<5.0a0' + libcxx: '>=15.0.7' + libdeflate: '>=1.19,<1.20.0a0' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libwebp-base: '>=1.3.2,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + xz: '>=5.2.6,<6.0a0' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.6.0-ha8a6c65_2.conda + hash: + md5: 596d6d949bab9a75a492d451f521f457 + sha256: b18ef36eb90f190db22c56ae5a080bccc16669c8f5b795a6211d7b0c00c18ff7 + category: main + optional: false +- name: libutf8proc + version: 2.8.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-h166bdaf_0.tar.bz2 + hash: + md5: ede4266dc02e875fe1ea77b25dd43747 + sha256: 49082ee8d01339b225f7f8c60f32a2a2c05fe3b16f31b554b4fb2c1dea237d1c + category: main + optional: false +- name: libutf8proc + version: 2.8.0 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libutf8proc-2.8.0-h1a8c8d9_0.tar.bz2 + hash: + md5: f8c9c41a122ab3abdf8943b13f4957ee + sha256: a3faddac08efd930fa3a1cc254b5053b4ed9428c49a888d437bf084d403c931a + category: main + optional: false +- name: libuuid + version: 2.38.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda + hash: + md5: 40b61aab5c7ba9ff276c41cfffe6b80b + sha256: 787eb542f055a2b3de553614b25f09eefb0a0931b0c87dbcce6efdfd92f04f18 + category: main + optional: false +- name: libuv + version: 1.46.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.46.0-hd590300_0.conda + hash: + md5: d23c76f7e6dcd6243d1b6ef5e62d17d2 + sha256: 4bc4c946e9a532c066442714eeeeb1ffbd03cd89789c4047293f5e782b5fedd7 + category: main + optional: false +- name: libuv + version: 1.46.0 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.46.0-hb547adb_0.conda + hash: + md5: 5f1d535f82e8210ac80d191610b92325 + sha256: f2fe8e22a99f91761c16dc7b00408bff0f5c30d4cccc6ea562db00a4041c5579 + category: main + optional: false +- name: libwebp + version: 1.3.2 + manager: conda + platform: linux-64 + dependencies: + giflib: '>=5.2.1,<5.3.0a0' + libgcc-ng: '>=12' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + libwebp-base: '>=1.3.2,<2.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libwebp-1.3.2-h658648e_1.conda + hash: + md5: 0ebb65e8d86843865796c7c95a941f34 + sha256: cc5e55531d8067ea379b145861aea8c749a545912bc016372f5e3c69cc925efd + category: main + optional: false +- name: libwebp + version: 1.3.2 + manager: conda + platform: osx-arm64 + dependencies: + giflib: '>=5.2.1,<5.3.0a0' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + libwebp-base: '>=1.3.2,<2.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-1.3.2-hf30222e_1.conda + hash: + md5: a07cf7f5425eb51b79880fb66837200f + sha256: 5ee611009277c8aaef1a5355df6a05100e563735ec33ef019f6415db0b83d548 + category: main + optional: false +- name: libwebp-base + version: 1.3.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.3.2-hd590300_0.conda + hash: + md5: 30de3fd9b3b602f7473f30e684eeea8c + sha256: 68764a760fa81ef35dacb067fe8ace452bbb41476536a4a147a1051df29525f0 + category: main + optional: false +- name: libwebp-base + version: 1.3.2 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.3.2-hb547adb_0.conda + hash: + md5: 85dbc11098cdbe4244cd73f29a3ab795 + sha256: a159b848193043fb58465ae6a449361615dadcf27babfe0b18db2bd3eb59e958 + category: main + optional: false +- name: libxcb + version: '1.15' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + pthread-stubs: '' + xorg-libxau: '' + xorg-libxdmcp: '' + url: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.15-h0b41bf4_0.conda + hash: + md5: 33277193f5b92bad9fdd230eb700929c + sha256: a670902f0a3173a466c058d2ac22ca1dd0df0453d3a80e0212815c20a16b0485 + category: main + optional: false +- name: libxcb + version: '1.15' + manager: conda + platform: osx-arm64 + dependencies: + pthread-stubs: '' + xorg-libxau: '' + xorg-libxdmcp: '' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.15-hf346824_0.conda + hash: + md5: 988d5f86ab60fa6de91b3ee3a88a3af9 + sha256: 6eaa87760ff3e91bb5524189700139db46f8946ff6331f4e571e4a9356edbb0d + category: main + optional: false +- name: libxml2 + version: 2.11.6 + manager: conda + platform: linux-64 + dependencies: + icu: '>=73.2,<74.0a0' + libgcc-ng: '>=12' + libiconv: '>=1.17,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + xz: '>=5.2.6,<6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.11.6-h232c23b_0.conda + hash: + md5: 427a3e59d66cb5d145020bd9c6493334 + sha256: e6183d5e57ee48cc1fc4340477c31a6bd8be4d3ba5dded82cbca0d5280591086 + category: main + optional: false +- name: libxml2 + version: 2.12.2 + manager: conda + platform: osx-arm64 + dependencies: + icu: '>=73.2,<74.0a0' + libiconv: '>=1.17,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + xz: '>=5.2.6,<6.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.12.2-h0d0cfa8_0.conda + hash: + md5: 54222818205b144ce5e3f4f10106d1a9 + sha256: be26a245e339105662be8c84bc00946079b1d792b36480d18d9bc52935d9af60 + category: main + optional: false +- name: libzip + version: 1.10.1 + manager: conda + platform: linux-64 + dependencies: + bzip2: '>=1.0.8,<2.0a0' + libgcc-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.2,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libzip-1.10.1-h2629f0a_3.conda + hash: + md5: ac79812548e7e8cf61f7b0abdef01d3b + sha256: 84e93f189072dcfcbe77744f19c7e4171523fbecfaba7352e5a23bbe014574c7 + category: main + optional: false +- name: libzlib + version: 1.2.13 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda + hash: + md5: f36c115f1ee199da648e0597ec2047ad + sha256: 370c7c5893b737596fd6ca0d9190c9715d89d888b8c88537ae1ef168c25e82e4 + category: main + optional: false +- name: libzlib + version: 1.2.13 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda + hash: + md5: 1a47f5236db2e06a320ffa0392f81bd8 + sha256: ab1c8aefa2d54322a63aaeeefe9cf877411851738616c4068e0dccc66b9c758a + category: main + optional: false +- name: llvm-openmp + version: 17.0.6 + manager: conda + platform: linux-64 + dependencies: + libzlib: '>=1.2.13,<1.3.0a0' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-17.0.6-h4dfa4b3_0.conda + hash: + md5: c1665f9c1c9f6c93d8b4e492a6a39056 + sha256: 18a9db4cc139e72e8eac80a34f6536491fe318d3785bc2c35fac42cd00676376 + category: main + optional: false +- name: llvm-openmp + version: 17.0.6 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-17.0.6-hcd81f8e_0.conda + hash: + md5: 52019d2fa0eddbbc4e6dcd30fae0c0a4 + sha256: 0c217326c5931c1416b82f98169b8a8a52139f6f5f299dbb2efa7b21f65f225a + category: main + optional: false +- name: locket + version: 1.0.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' + url: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 91e27ef3d05cc772ce627e51cff111c4 + sha256: 9afe0b5cfa418e8bdb30d8917c5a6cec10372b037924916f1f85b9f4899a67a6 + category: main + optional: false +- name: locket + version: 1.0.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' + url: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 91e27ef3d05cc772ce627e51cff111c4 + sha256: 9afe0b5cfa418e8bdb30d8917c5a6cec10372b037924916f1f85b9f4899a67a6 + category: main + optional: false +- name: lz4 + version: 4.3.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + lz4-c: '>=1.9.3,<1.10.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/lz4-4.3.2-py39h79d96da_1.conda + hash: + md5: 098feecfa5d91726caf654b67c9e7190 + sha256: e99b7cab72a80429d6231149c18266a2b27318aa838aa1b29c0944dbe5efc69c + category: main + optional: false +- name: lz4 + version: 4.3.2 + manager: conda + platform: osx-arm64 + dependencies: + lz4-c: '>=1.9.3,<1.10.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-4.3.2-py39h0d94542_1.conda + hash: + md5: 53809d9356529ecf1d2ccfde9dbf1c64 + sha256: aa0c9d0b4fee03e0e05a2e3767c30ff3fdb7716e80a3eb22d29a778bec7e3134 + category: main + optional: false +- name: lz4-c + version: 1.9.4 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda + hash: + md5: 318b08df404f9c9be5712aaa5a6f0bb0 + sha256: 1b4c105a887f9b2041219d57036f72c4739ab9e9fe5a1486f094e58c76b31f5f + category: main + optional: false +- name: lz4-c + version: 1.9.4 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=14.0.6' + url: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.9.4-hb7217d7_0.conda + hash: + md5: 45505bec548634f7d05e02fb25262cb9 + sha256: fc343b8c82efe40819b986e29ba748366514e5ab94a1e1138df195af5f45fa24 + category: main + optional: false +- name: lzo + version: '2.10' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=7.5.0' + url: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h516909a_1000.tar.bz2 + hash: + md5: bb14fcb13341b81d5eb386423b9d2bac + sha256: 25d16e6aaa3d0b450e61d0c4fadd7c9fd17f16e2fef09b34507209342d63c9f6 + category: main + optional: false +- name: makefun + version: 1.15.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/makefun-1.15.2-pyhd8ed1ab_0.conda + hash: + md5: f0ebb89ab17982033d8f0fea244b0822 + sha256: bcd48b9d591a5cc97803701c25aeec06122baf3af4e799e764eddcede112533b + category: main + optional: false +- name: makefun + version: 1.15.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/makefun-1.15.2-pyhd8ed1ab_0.conda + hash: + md5: f0ebb89ab17982033d8f0fea244b0822 + sha256: bcd48b9d591a5cc97803701c25aeec06122baf3af4e799e764eddcede112533b + category: main + optional: false +- name: mako + version: 1.3.0 + manager: conda + platform: linux-64 + dependencies: + importlib-metadata: '' + markupsafe: '>=0.9.2' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/mako-1.3.0-pyhd8ed1ab_0.conda + hash: + md5: 92ca4a92d34ed6e8fa38d93c8552c346 + sha256: b3c0353790ae5a5ebb54aa339661083a6234e5193e758668e62ba36c48dc3c94 + category: main + optional: false +- name: mako + version: 1.3.0 + manager: conda + platform: osx-arm64 + dependencies: + importlib-metadata: '' + python: '>=3.6' + markupsafe: '>=0.9.2' + url: https://conda.anaconda.org/conda-forge/noarch/mako-1.3.0-pyhd8ed1ab_0.conda + hash: + md5: 92ca4a92d34ed6e8fa38d93c8552c346 + sha256: b3c0353790ae5a5ebb54aa339661083a6234e5193e758668e62ba36c48dc3c94 + category: main + optional: false +- name: mapclassify + version: 2.6.1 + manager: conda + platform: linux-64 + dependencies: + networkx: '>=2.7' + numpy: '>=1.23' + pandas: '>=1.4,!=1.5.0' + python: '>=3.9' + scikit-learn: '>=1.0' + scipy: '>=1.8' + url: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.6.1-pyhd8ed1ab_0.conda + hash: + md5: 6aceae1ad4f16cf7b73ee04189947f98 + sha256: 204ab8b242229d422b33cfec07ea61cefa8bd22375a16658afbabaafce031d64 + category: main + optional: false +- name: markdown + version: 3.5.1 + manager: conda + platform: linux-64 + dependencies: + importlib-metadata: '>=4.4' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/markdown-3.5.1-pyhd8ed1ab_0.conda + hash: + md5: 323495027ffa625701129acebf861412 + sha256: 35e8990504cf8dc7e2bb63efd855fb0a0d5c0d77bf79403235e757c24a83ec1d + category: main + optional: false +- name: markdown + version: 3.5.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + importlib-metadata: '>=4.4' + url: https://conda.anaconda.org/conda-forge/noarch/markdown-3.5.1-pyhd8ed1ab_0.conda + hash: + md5: 323495027ffa625701129acebf861412 + sha256: 35e8990504cf8dc7e2bb63efd855fb0a0d5c0d77bf79403235e757c24a83ec1d + category: main + optional: false +- name: markdown-it-py + version: 2.2.0 + manager: conda + platform: linux-64 + dependencies: + mdurl: '>=0.1,<1' + python: '>=3.7' + typing_extensions: '>=3.7.4' + url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-2.2.0-pyhd8ed1ab_0.conda + hash: + md5: b2928a6c6d52d7e3562b4a59c3214e3a + sha256: 65ed439862c1851463f03a9bc5109992ce3e3e025e9a2d76d13ca19f576eee9f + category: main + optional: false +- name: markdown-it-py + version: 2.2.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + typing_extensions: '>=3.7.4' + mdurl: '>=0.1,<1' + url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-2.2.0-pyhd8ed1ab_0.conda + hash: + md5: b2928a6c6d52d7e3562b4a59c3214e3a + sha256: 65ed439862c1851463f03a9bc5109992ce3e3e025e9a2d76d13ca19f576eee9f + category: main + optional: false +- name: markupsafe + version: 2.1.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-2.1.3-py39hd1e30aa_1.conda + hash: + md5: ee2b4665b852ec6ff2758f3c1b91233d + sha256: 0fb7a5340855c0b3c7c9259eb57ff00abedf36530ba1daae3434016301b0fa36 + category: main + optional: false +- name: markupsafe + version: 2.1.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-2.1.3-py39h0f82c59_1.conda + hash: + md5: 38e2896c8caf4950b63389f8211763de + sha256: 84ece0e2760824b00b217e387632dfc0e7975e1a255e97d1b8cce057a0970c19 + category: main + optional: false +- name: marshmallow + version: 3.20.1 + manager: conda + platform: linux-64 + dependencies: + packaging: '>=17.0' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/marshmallow-3.20.1-pyhd8ed1ab_0.conda + hash: + md5: 0a33d141ff5f5dfbf9306f8408e9b520 + sha256: ff761f3a2dc70b8451e482b38222da195143d75c83f7607b72eddda57b5eec12 + category: main + optional: false +- name: marshmallow + version: 3.20.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + packaging: '>=17.0' + url: https://conda.anaconda.org/conda-forge/noarch/marshmallow-3.20.1-pyhd8ed1ab_0.conda + hash: + md5: 0a33d141ff5f5dfbf9306f8408e9b520 + sha256: ff761f3a2dc70b8451e482b38222da195143d75c83f7607b72eddda57b5eec12 + category: main + optional: false +- name: marshmallow-enum + version: 1.5.1 + manager: conda + platform: linux-64 + dependencies: + marshmallow: '>=2.0.0' + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/marshmallow-enum-1.5.1-pyh9f0ad1d_3.tar.bz2 + hash: + md5: 67c5202bf14543cd1bb97f129d3f26dd + sha256: 7729d878c2129d691e86b81fce346320a0152a6bbfc862a8c12ec646763f4857 + category: main + optional: false +- name: marshmallow-enum + version: 1.5.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + marshmallow: '>=2.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/marshmallow-enum-1.5.1-pyh9f0ad1d_3.tar.bz2 + hash: + md5: 67c5202bf14543cd1bb97f129d3f26dd + sha256: 7729d878c2129d691e86b81fce346320a0152a6bbfc862a8c12ec646763f4857 + category: main + optional: false +- name: marshmallow-jsonschema + version: 0.13.0 + manager: conda + platform: linux-64 + dependencies: + marshmallow: '>=3.11' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/marshmallow-jsonschema-0.13.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: bd47c87386365fcaf782c9c407b50507 + sha256: 74c6bd772e9ed1b33bdb216737186eae36fca27dbf0e1cb6bd9847494f08c9d6 + category: main + optional: false +- name: marshmallow-jsonschema + version: 0.13.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + marshmallow: '>=3.11' + url: https://conda.anaconda.org/conda-forge/noarch/marshmallow-jsonschema-0.13.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: bd47c87386365fcaf782c9c407b50507 + sha256: 74c6bd772e9ed1b33bdb216737186eae36fca27dbf0e1cb6bd9847494f08c9d6 + category: main + optional: false +- name: mashumaro + version: '3.11' + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + typing-extensions: '>=4.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/mashumaro-3.11-pyhd8ed1ab_0.conda + hash: + md5: b831d76378b72084746bfcd01658989b + sha256: 07af0f5d0b721deb4c152525468109a70670fa93a92a1c1c339aed176ec1eb34 + category: main + optional: false +- name: mashumaro + version: '3.11' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + typing-extensions: '>=4.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/mashumaro-3.11-pyhd8ed1ab_0.conda + hash: + md5: b831d76378b72084746bfcd01658989b + sha256: 07af0f5d0b721deb4c152525468109a70670fa93a92a1c1c339aed176ec1eb34 + category: main + optional: false +- name: matplotlib-base + version: 3.8.2 + manager: conda + platform: linux-64 + dependencies: + certifi: '>=2020.06.20' + contourpy: '>=1.0.1' + cycler: '>=0.10' + fonttools: '>=4.22.0' + freetype: '>=2.12.1,<3.0a0' + importlib-resources: '>=3.2.0' + kiwisolver: '>=1.3.1' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + numpy: '>=1.22.4,<2.0a0' + packaging: '>=20.0' + pillow: '>=8' + pyparsing: '>=2.3.1' + python: '>=3.9,<3.10.0a0' + python-dateutil: '>=2.7' + python_abi: 3.9.* + tk: '>=8.6.13,<8.7.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.8.2-py39he9076e7_0.conda + hash: + md5: 6085411aa2f0b2b801d3b46e1d3b83c5 + sha256: f5e1275e1e7f644d5c91780c08f9868153b8b1a00703e7b03f4b171be02879e1 + category: main + optional: false +- name: matplotlib-base + version: 3.8.2 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + certifi: '>=2020.06.20' + contourpy: '>=1.0.1' + cycler: '>=0.10' + fonttools: '>=4.22.0' + freetype: '>=2.12.1,<3.0a0' + importlib-resources: '>=3.2.0' + kiwisolver: '>=1.3.1' + libcxx: '>=16.0.6' + numpy: '>=1.22.4,<2.0a0' + packaging: '>=20.0' + pillow: '>=8' + pyparsing: '>=2.3.1' + python: '>=3.9,<3.10.0a0' + python-dateutil: '>=2.7' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.8.2-py39h1a09f3e_0.conda + hash: + md5: 98e278f5a585b596276064e25affcf11 + sha256: 904f0e7c2a88fc55407560bcd94d44b54ec916e57540c5f53ca631eb276df5f0 + category: main + optional: false +- name: matplotlib-inline + version: 0.1.6 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + traitlets: '' + url: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.6-pyhd8ed1ab_0.tar.bz2 + hash: + md5: b21613793fcc81d944c76c9f2864a7de + sha256: aa091b88aec55bfa2d9207028d8cdc689b9efb090ae27b99557e93c675be2f3c + category: main + optional: false +- name: matplotlib-inline + version: 0.1.6 + manager: conda + platform: osx-arm64 + dependencies: + traitlets: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.6-pyhd8ed1ab_0.tar.bz2 + hash: + md5: b21613793fcc81d944c76c9f2864a7de + sha256: aa091b88aec55bfa2d9207028d8cdc689b9efb090ae27b99557e93c675be2f3c + category: main + optional: false +- name: mdit-py-plugins + version: 0.4.0 + manager: conda + platform: linux-64 + dependencies: + markdown-it-py: '>=1.0.0,<4.0.0' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.4.0-pyhd8ed1ab_0.conda + hash: + md5: 6c5358a10873a15398b6f15f60cb5e1f + sha256: 1ddac8d2be448cd1fbe49d2ca09df7e10d99679d53146a917f8bb4899f76d0ca + category: main + optional: false +- name: mdit-py-plugins + version: 0.4.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + markdown-it-py: '>=1.0.0,<4.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.4.0-pyhd8ed1ab_0.conda + hash: + md5: 6c5358a10873a15398b6f15f60cb5e1f + sha256: 1ddac8d2be448cd1fbe49d2ca09df7e10d99679d53146a917f8bb4899f76d0ca + category: main + optional: false +- name: mdurl + version: 0.1.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: f8dab71fdc13b1bf29a01248b156d268 + sha256: c678b9194e025b1fb665bec30ee20aab93399203583875b1dcc0a3b52a8f5523 + category: main + optional: false +- name: mdurl + version: 0.1.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: f8dab71fdc13b1bf29a01248b156d268 + sha256: c678b9194e025b1fb665bec30ee20aab93399203583875b1dcc0a3b52a8f5523 + category: main + optional: false +- name: minizip + version: 4.0.3 + manager: conda + platform: linux-64 + dependencies: + bzip2: '>=1.0.8,<2.0a0' + libgcc-ng: '>=12' + libiconv: '>=1.17,<2.0a0' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.4,<4.0a0' + xz: '>=5.2.6,<6.0a0' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.3-h0ab5242_0.conda + hash: + md5: 3f9b5f4400be3cee11b426a8cd653b7c + sha256: cf33c24fa8375d17fad4e1da631b4c2e8ed9a109480fa45c82fbfa2a7c5bdd41 + category: main + optional: false +- name: mistune + version: 3.0.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/mistune-3.0.2-pyhd8ed1ab_0.conda + hash: + md5: 5cbee699846772cc939bef23a0d524ed + sha256: f95cb70007e3cc2ba44e17c29a056b499e6dadf08746706d0c817c8e2f47e05c + category: main + optional: false +- name: mistune + version: 3.0.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/mistune-3.0.2-pyhd8ed1ab_0.conda + hash: + md5: 5cbee699846772cc939bef23a0d524ed + sha256: f95cb70007e3cc2ba44e17c29a056b499e6dadf08746706d0c817c8e2f47e05c + category: main + optional: false +- name: mkl + version: 2022.2.1 + manager: conda + platform: linux-64 + dependencies: + _openmp_mutex: '>=4.5' + llvm-openmp: '>=15.0.6' + tbb: 2021.* + url: https://conda.anaconda.org/conda-forge/linux-64/mkl-2022.2.1-h84fe81f_16997.conda + hash: + md5: a7ce56d5757f5b57e7daabe703ade5bb + sha256: 5322750d5e96ff5d96b1457db5fb6b10300f2bc4030545e940e17b57c4e96d00 + category: main + optional: false +- name: ml_dtypes + version: 0.2.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + numpy: '>=1.22.4,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/ml_dtypes-0.2.0-py39hddac248_2.conda + hash: + md5: 97e48908f75e32b0382b1aba3a3dbffe + sha256: 075bc750ecd95c7fc64be32181a6818d2bb7e9a965123c7eb8f1e0f3e29ab00a + category: main + optional: false +- name: ml_dtypes + version: 0.2.0 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + numpy: '>=1.22.4,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/ml_dtypes-0.2.0-py39h425d09f_2.conda + hash: + md5: fca115234f1e7a90837de288b4c95a55 + sha256: 24679381454425b654c2677afb4f227c88fdf56edc1aac520f3815b8f35a3708 + category: main + optional: false +- name: mlflow + version: 2.7.0 + manager: conda + platform: linux-64 + dependencies: + alembic: <2,!=1.10 + click: '>=7.0,<9' + cloudpickle: <3 + databricks-cli: '>=0.8.7,<1' + docker-py: '>=4.0.0,<7' + entrypoints: <1 + flask: <3 + gitpython: '>=2.1.0,<4' + gunicorn: <22 + importlib-metadata: <7,>=3.7.0,!=4.7.0 + jinja2: <4,>=2.11 + markdown: <4,>=3.3 + matplotlib-base: <4 + numpy: <2 + openssl: '' + packaging: <24 + pandas: <3 + prometheus_flask_exporter: <1 + protobuf: '>=3.12.0,<5' + pyarrow: <14,>=4.0.0 + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + pytz: <2024 + pyyaml: '>=5.1,<7' + querystring_parser: <2 + requests: '>=2.17.3,<3' + scikit-learn: <2 + scipy: <2 + sqlalchemy: '>=1.4.0,<3' + sqlparse: '>=0.4.0,<1' + url: https://conda.anaconda.org/conda-forge/linux-64/mlflow-2.7.0-py39ha39b057_0.conda + hash: + md5: e648a19e6574b337e7f3e50845c05421 + sha256: 8c973c4dfe492f7141c0ba9513e273ed31cf51f80b173d3f0f7c6f681914c7e7 + category: main + optional: false +- name: mlflow + version: 2.7.0 + manager: conda + platform: osx-arm64 + dependencies: + alembic: <2,!=1.10 + click: '>=7.0,<9' + cloudpickle: <3 + databricks-cli: '>=0.8.7,<1' + docker-py: '>=4.0.0,<7' + entrypoints: <1 + flask: <3 + gitpython: '>=2.1.0,<4' + gunicorn: <22 + importlib-metadata: <7,>=3.7.0,!=4.7.0 + jinja2: <4,>=2.11 + markdown: <4,>=3.3 + matplotlib-base: <4 + numpy: <2 + openssl: '' + packaging: <24 + pandas: <3 + prometheus_flask_exporter: <1 + protobuf: '>=3.12.0,<5' + pyarrow: <14,>=4.0.0 + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + pytz: <2024 + pyyaml: '>=5.1,<7' + querystring_parser: <2 + requests: '>=2.17.3,<3' + scikit-learn: <2 + scipy: <2 + sqlalchemy: '>=1.4.0,<3' + sqlparse: '>=0.4.0,<1' + url: https://conda.anaconda.org/conda-forge/osx-arm64/mlflow-2.7.0-py39h3c3ad29_0.conda + hash: + md5: 669b33b508bd24330f169b452c92b2be + sha256: cf668816112d69cd77d36fcaae06d0ca6c7a9a842e2d96eec8defd9931e71d71 + category: main + optional: false +- name: modin + version: 0.22.3 + manager: conda + platform: linux-64 + dependencies: + modin-dask: 0.22.3 + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/modin-0.22.3-py39hf3d152e_0.conda + hash: + md5: 88b3e075452ea617716af838a80237df + sha256: a169089f9fbaa73eec10fe27b3a2bf15e5251bec930fc09fca6b39642765dc75 + category: main + optional: false +- name: modin + version: 0.8.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + dask: '>=2.1.0' + distributed: '>=2.3.2' + pandas: 1.1.4 + url: https://conda.anaconda.org/conda-forge/noarch/modin-0.8.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: a42e5ad474f76e75db0469cdb7da8b59 + sha256: 20347140b5feb242d756bbfbf25b5bee7636d3ff87c9001b7c95e6a55fc7e2df + category: main + optional: false +- name: modin-core + version: 0.22.3 + manager: conda + platform: linux-64 + dependencies: + fsspec: '' + numpy: '>=1.18.5' + packaging: '' + pandas: 1.5.3 + psutil: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/modin-core-0.22.3-py39hf3d152e_0.conda + hash: + md5: 821b7983b179c259abe5295f59c079ea + sha256: d9c8a8425c255048e911934af8b1009509c9a5b5ff1f3cdbac84e6b3bdc1a82a + category: main + optional: false +- name: modin-dask + version: 0.22.3 + manager: conda + platform: linux-64 + dependencies: + dask: '>=2.22.0' + distributed: '>=2.22.0' + modin-core: 0.22.3 + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/modin-dask-0.22.3-py39hf3d152e_0.conda + hash: + md5: 4f514fb1232a6b05d0e5b198337a2bca + sha256: aada21014ca8b7bf3790bec16184120c06dbea78f0f5d550a9b28749c6032c23 + category: main + optional: false +- name: more-itertools + version: 10.1.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.1.0-pyhd8ed1ab_0.conda + hash: + md5: 8549fafed0351bbfaa1ddaa15fdf9b4e + sha256: 07ce65497dec537e490992758934ddbc4fb5ed9285b41387a7cca966f1a98a0f + category: main + optional: false +- name: more-itertools + version: 10.1.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.1.0-pyhd8ed1ab_0.conda + hash: + md5: 8549fafed0351bbfaa1ddaa15fdf9b4e + sha256: 07ce65497dec537e490992758934ddbc4fb5ed9285b41387a7cca966f1a98a0f + category: main + optional: false +- name: mpc + version: 1.3.1 + manager: conda + platform: linux-64 + dependencies: + gmp: '>=6.2.1,<7.0a0' + libgcc-ng: '>=12' + mpfr: '>=4.1.0,<5.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-hfe3b2da_0.conda + hash: + md5: 289c71e83dc0daa7d4c81f04180778ca + sha256: 2f88965949ba7b4b21e7e5facd62285f7c6efdb17359d1b365c3bb4ecc968d29 + category: main + optional: false +- name: mpc + version: 1.3.1 + manager: conda + platform: osx-arm64 + dependencies: + gmp: '>=6.2.1,<7.0a0' + mpfr: '>=4.1.0,<5.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.3.1-h91ba8db_0.conda + hash: + md5: 362af269d860ae49580f8f032a68b0df + sha256: 6d8d4f8befca279f022c1c212241ad6672cb347181452555414e277484ad534c + category: main + optional: false +- name: mpfr + version: 4.2.1 + manager: conda + platform: linux-64 + dependencies: + gmp: '>=6.2.1,<7.0a0' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h9458935_0.conda + hash: + md5: 4c28f3210b30250037a4a627eeee9e0f + sha256: 008230a53ff15cf61966476b44f7ba2c779826825b9ca639a0a2b44d8f7aa6cb + category: main + optional: false +- name: mpfr + version: 4.2.1 + manager: conda + platform: osx-arm64 + dependencies: + gmp: '>=6.2.1,<7.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.1-h9546428_0.conda + hash: + md5: a0d56e1ff4ac1babc2e95516aeba7d24 + sha256: 811ca63177cf638ac01442fc8d1148d3a0cef18dc1f870fceed1feb24be6fd8f + category: main + optional: false +- name: mpmath + version: 1.3.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_0.conda + hash: + md5: dbf6e2d89137da32fa6670f3bffc024e + sha256: a4f025c712ec1502a55c471b56a640eaeebfce38dd497d5a1a33729014cac47a + category: main + optional: false +- name: mpmath + version: 1.3.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_0.conda + hash: + md5: dbf6e2d89137da32fa6670f3bffc024e + sha256: a4f025c712ec1502a55c471b56a640eaeebfce38dd497d5a1a33729014cac47a + category: main + optional: false +- name: msal + version: 1.26.0 + manager: conda + platform: linux-64 + dependencies: + cryptography: <44,>=0.6 + pyjwt: <3,>=1.0.0 + python: '>=3.6' + requests: <3,>=2.0.0 + url: https://conda.anaconda.org/conda-forge/noarch/msal-1.26.0-pyhd8ed1ab_0.conda + hash: + md5: 9d9b0ef23f5dbe0d612ca037b9bfb410 + sha256: e0eb5606b4a164964d663d7a215ac9cd18db1ce1eca544aa61348e0a2bda94a9 + category: main + optional: false +- name: msal + version: 1.26.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + cryptography: <44,>=0.6 + pyjwt: <3,>=1.0.0 + requests: <3,>=2.0.0 + url: https://conda.anaconda.org/conda-forge/noarch/msal-1.26.0-pyhd8ed1ab_0.conda + hash: + md5: 9d9b0ef23f5dbe0d612ca037b9bfb410 + sha256: e0eb5606b4a164964d663d7a215ac9cd18db1ce1eca544aa61348e0a2bda94a9 + category: main + optional: false +- name: msal_extensions + version: 1.0.0 + manager: conda + platform: linux-64 + dependencies: + msal: '>=0.4.1,<2.0' + portalocker: '>=1.6,<3.0' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/msal_extensions-1.0.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: db0e3cc6e5e99baf237a2ab73898f553 + sha256: 73096cb7f0939595651fb1555a201b3a31adb3dfeb833e70af2d4313015dd51f + category: main + optional: false +- name: msal_extensions + version: 1.0.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + msal: '>=0.4.1,<2.0' + portalocker: '>=1.6,<3.0' + url: https://conda.anaconda.org/conda-forge/noarch/msal_extensions-1.0.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: db0e3cc6e5e99baf237a2ab73898f553 + sha256: 73096cb7f0939595651fb1555a201b3a31adb3dfeb833e70af2d4313015dd51f + category: main + optional: false +- name: msgpack-python + version: 1.0.7 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.0.7-py39h7633fee_0.conda + hash: + md5: f668e146a2ed03a4e62ffbb98b3115fb + sha256: a47f46861f206043602b5f8b176e3957dd4a59876b819a2e089d63d52e312412 + category: main + optional: false +- name: msgpack-python + version: 1.0.7 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + libcxx: '>=16.0.6' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.0.7-py39he9de807_0.conda + hash: + md5: 83b1e425c68e873c9b3096d7e01267fb + sha256: ba0e84b3fdccd3c81b2a9e0d84eaddb2a67e67fc416e6ebaade6866572b470af + category: main + optional: false +- name: multidict + version: 6.0.4 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/multidict-6.0.4-py39hd1e30aa_1.conda + hash: + md5: 6c87066b599dc8d932437abdc65ed4b9 + sha256: fc292f5174cf9f8669fe144e8ed4c1b79d3061a92e60bca58d189194e65f4959 + category: main + optional: false +- name: multidict + version: 6.0.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/multidict-6.0.4-py39h02fc5c5_1.conda + hash: + md5: a73bf93d2051be85485b381570dfd1da + sha256: 9bf0acebfa00647f98593179927751e3f9b5ff2bb052419e677f143314543bc1 + category: main + optional: false +- name: multimethod + version: 1.9.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/multimethod-1.9.1-pyhd8ed1ab_0.conda + hash: + md5: 48223af3f697ccd9b114adb6a66e0f11 + sha256: 7fcfda7b4a1d74205fcfdefd93804226a6eaffc74a319414c7d8d88f9249db3b + category: main + optional: false +- name: multimethod + version: 1.9.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/multimethod-1.9.1-pyhd8ed1ab_0.conda + hash: + md5: 48223af3f697ccd9b114adb6a66e0f11 + sha256: 7fcfda7b4a1d74205fcfdefd93804226a6eaffc74a319414c7d8d88f9249db3b + category: main + optional: false +- name: multiprocess + version: 0.70.15 + manager: conda + platform: linux-64 + dependencies: + dill: '>=0.3.6' + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/multiprocess-0.70.15-py39hd1e30aa_1.conda + hash: + md5: ba981804a87d06ba9899e938c3178ed2 + sha256: 7f9c6d04b5ec3df502599ebd3e86a95194bb7358d70c23374f8b71a89040194a + category: main + optional: false +- name: multiprocess + version: 0.70.15 + manager: conda + platform: osx-arm64 + dependencies: + dill: '>=0.3.6' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/multiprocess-0.70.15-py39h0f82c59_1.conda + hash: + md5: 3b94f36e225c5b5fe8d37ce3577cf72c + sha256: 0675aaf60406afb644f42b714f58979feaa99892e98aca83b81b8376df7b5997 + category: main + optional: false +- name: munch + version: 4.0.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/munch-4.0.0-pyhd8ed1ab_0.conda + hash: + md5: 376b32e8f9d3eacbd625f37d39bd507d + sha256: 093020ae2deb6c468120111a54909e1c576d70dfea6bc0eec5093e36d2fb8ff8 + category: main + optional: false +- name: munkres + version: 1.1.4 + manager: conda + platform: linux-64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 + hash: + md5: 2ba8498c1018c1e9c61eb99b973dfe19 + sha256: f86fb22b58e93d04b6f25e0d811b56797689d598788b59dcb47f59045b568306 + category: main + optional: false +- name: munkres + version: 1.1.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 + hash: + md5: 2ba8498c1018c1e9c61eb99b973dfe19 + sha256: f86fb22b58e93d04b6f25e0d811b56797689d598788b59dcb47f59045b568306 + category: main + optional: false +- name: mypy_extensions + version: 1.0.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda + hash: + md5: 4eccaeba205f0aed9ac3a9ea58568ca3 + sha256: f240217476e148e825420c6bc3a0c0efb08c0718b7042fae960400c02af858a3 + category: main + optional: false +- name: mypy_extensions + version: 1.0.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda + hash: + md5: 4eccaeba205f0aed9ac3a9ea58568ca3 + sha256: f240217476e148e825420c6bc3a0c0efb08c0718b7042fae960400c02af858a3 + category: main + optional: false +- name: myst-nb + version: 0.17.2 + manager: conda + platform: linux-64 + dependencies: + importlib-metadata: '' + ipykernel: '' + ipython: '' + jupyter-cache: '>=0.5.0,<0.7.0' + myst-parser: '>=0.18.0,<0.19.0' + nbclient: '' + nbformat: '>=5.0,<6' + python: '>=3.7' + pyyaml: '' + sphinx: '>=4,<6' + typing_extensions: '' + url: https://conda.anaconda.org/conda-forge/noarch/myst-nb-0.17.2-pyhd8ed1ab_0.conda + hash: + md5: 40190b7d06f86b63d28fa78aaa39c023 + sha256: 37bcf6de8618a0668ef6b364b14e0eceea87b202a3882c59dcd85bc1172a5402 + category: main + optional: false +- name: myst-nb + version: 0.17.2 + manager: conda + platform: osx-arm64 + dependencies: + pyyaml: '' + typing_extensions: '' + ipython: '' + importlib-metadata: '' + ipykernel: '' + nbclient: '' + python: '>=3.7' + nbformat: '>=5.0,<6' + sphinx: '>=4,<6' + myst-parser: '>=0.18.0,<0.19.0' + jupyter-cache: '>=0.5.0,<0.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/myst-nb-0.17.2-pyhd8ed1ab_0.conda + hash: + md5: 40190b7d06f86b63d28fa78aaa39c023 + sha256: 37bcf6de8618a0668ef6b364b14e0eceea87b202a3882c59dcd85bc1172a5402 + category: main + optional: false +- name: myst-parser + version: 0.18.1 + manager: conda + platform: linux-64 + dependencies: + docutils: '>=0.15,<0.20' + jinja2: '' + markdown-it-py: '>=1.0.0,<3.0.0' + mdit-py-plugins: '>=0.3.1,<1' + python: '>=3.7' + pyyaml: '' + sphinx: '>=4,<6' + typing-extensions: '' + url: https://conda.anaconda.org/conda-forge/noarch/myst-parser-0.18.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: bcfdf5c7d8bf5c6f6be7b4c66fff2eca + sha256: 260812a430adee3598103d75704c1c855a9816a3895971ca0190d0f5e1e8165a + category: main + optional: false +- name: myst-parser + version: 0.18.1 + manager: conda + platform: osx-arm64 + dependencies: + pyyaml: '' + typing-extensions: '' + jinja2: '' + python: '>=3.7' + markdown-it-py: '>=1.0.0,<3.0.0' + sphinx: '>=4,<6' + docutils: '>=0.15,<0.20' + mdit-py-plugins: '>=0.3.1,<1' + url: https://conda.anaconda.org/conda-forge/noarch/myst-parser-0.18.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: bcfdf5c7d8bf5c6f6be7b4c66fff2eca + sha256: 260812a430adee3598103d75704c1c855a9816a3895971ca0190d0f5e1e8165a + category: main + optional: false +- name: nbclient + version: 0.7.4 + manager: conda + platform: linux-64 + dependencies: + jupyter_client: '>=6.1.12' + jupyter_core: '>=4.12,!=5.0.*' + nbformat: '>=5.1' + python: '>=3.7' + traitlets: '>=5.3' + url: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.7.4-pyhd8ed1ab_0.conda + hash: + md5: f7aa15f77d29b11caa1df1eb15383c59 + sha256: f26afcbbdd4bd1245db514c6ebc6ef18cc12067145dcab229b6f88653575d44c + category: main + optional: false +- name: nbclient + version: 0.7.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + jupyter_client: '>=6.1.12' + jupyter_core: '>=4.12,!=5.0.*' + nbformat: '>=5.1' + traitlets: '>=5.3' + url: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.7.4-pyhd8ed1ab_0.conda + hash: + md5: f7aa15f77d29b11caa1df1eb15383c59 + sha256: f26afcbbdd4bd1245db514c6ebc6ef18cc12067145dcab229b6f88653575d44c + category: main + optional: false +- name: nbconvert + version: 7.12.0 + manager: conda + platform: linux-64 + dependencies: + nbconvert-core: 7.12.0 + nbconvert-pandoc: 7.12.0 + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.12.0-pyhd8ed1ab_0.conda + hash: + md5: 364e28ab12477494e72839aaa588073d + sha256: 0137330ab16bddf1fcaf60c0501c6145705b775fd547823708ed84364c934b76 + category: main + optional: false +- name: nbconvert + version: 7.12.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + nbconvert-core: 7.12.0 + nbconvert-pandoc: 7.12.0 + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.12.0-pyhd8ed1ab_0.conda + hash: + md5: 364e28ab12477494e72839aaa588073d + sha256: 0137330ab16bddf1fcaf60c0501c6145705b775fd547823708ed84364c934b76 + category: main + optional: false +- name: nbconvert-core + version: 7.12.0 + manager: conda + platform: linux-64 + dependencies: + beautifulsoup4: '' + bleach: '' + defusedxml: '' + entrypoints: '>=0.2.2' + jinja2: '>=3.0' + jupyter_core: '>=4.7' + jupyterlab_pygments: '' + markupsafe: '>=2.0' + mistune: '>=2.0.3,<4' + nbclient: '>=0.5.0' + nbformat: '>=5.1' + packaging: '' + pandocfilters: '>=1.4.1' + pygments: '>=2.4.1' + python: '>=3.8' + tinycss2: '' + traitlets: '>=5.0' + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.12.0-pyhd8ed1ab_0.conda + hash: + md5: 4d67c68fd0d130091ada039bc2d81b33 + sha256: 04c3ac88701d98d58139569e4899c3254bf99908179a898cc3dcadd8c0ef44b4 + category: main + optional: false +- name: nbconvert-core + version: 7.12.0 + manager: conda + platform: osx-arm64 + dependencies: + packaging: '' + beautifulsoup4: '' + defusedxml: '' + bleach: '' + tinycss2: '' + jupyterlab_pygments: '' + python: '>=3.8' + jinja2: '>=3.0' + entrypoints: '>=0.2.2' + traitlets: '>=5.0' + markupsafe: '>=2.0' + jupyter_core: '>=4.7' + pandocfilters: '>=1.4.1' + nbformat: '>=5.1' + pygments: '>=2.4.1' + nbclient: '>=0.5.0' + mistune: '>=2.0.3,<4' + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.12.0-pyhd8ed1ab_0.conda + hash: + md5: 4d67c68fd0d130091ada039bc2d81b33 + sha256: 04c3ac88701d98d58139569e4899c3254bf99908179a898cc3dcadd8c0ef44b4 + category: main + optional: false +- name: nbconvert-pandoc + version: 7.12.0 + manager: conda + platform: linux-64 + dependencies: + nbconvert-core: 7.12.0 + pandoc: '' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.12.0-pyhd8ed1ab_0.conda + hash: + md5: 460d7cac50322a39b61a833885a6a8d5 + sha256: ebf25caef387ec79f8d8f6771240d451ffaebcc2cdd127c0b152c6697d661d10 + category: main + optional: false +- name: nbconvert-pandoc + version: 7.12.0 + manager: conda + platform: osx-arm64 + dependencies: + pandoc: '' + python: '>=3.8' + nbconvert-core: 7.12.0 + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.12.0-pyhd8ed1ab_0.conda + hash: + md5: 460d7cac50322a39b61a833885a6a8d5 + sha256: ebf25caef387ec79f8d8f6771240d451ffaebcc2cdd127c0b152c6697d661d10 + category: main + optional: false +- name: nbformat + version: 5.9.2 + manager: conda + platform: linux-64 + dependencies: + jsonschema: '>=2.6' + jupyter_core: '' + python: '>=3.8' + python-fastjsonschema: '' + traitlets: '>=5.1' + url: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.9.2-pyhd8ed1ab_0.conda + hash: + md5: 61ba076de6530d9301a0053b02f093d2 + sha256: fc82c5a9116820757b03ffb836b36f0f50e4cd390018024dbadb0ee0217f6992 + category: main + optional: false +- name: nbformat + version: 5.9.2 + manager: conda + platform: osx-arm64 + dependencies: + jupyter_core: '' + python-fastjsonschema: '' + python: '>=3.8' + traitlets: '>=5.1' + jsonschema: '>=2.6' + url: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.9.2-pyhd8ed1ab_0.conda + hash: + md5: 61ba076de6530d9301a0053b02f093d2 + sha256: fc82c5a9116820757b03ffb836b36f0f50e4cd390018024dbadb0ee0217f6992 + category: main + optional: false +- name: ncurses + version: '6.4' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-h59595ed_2.conda + hash: + md5: 7dbaa197d7ba6032caf7ae7f32c1efa0 + sha256: 91cc03f14caf96243cead96c76fe91ab5925a695d892e83285461fb927dece5e + category: main + optional: false +- name: ncurses + version: '6.4' + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + url: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.4-h463b476_2.conda + hash: + md5: 52b6f254a7b9663e854f44b6570ed982 + sha256: f6890634f815e8408d08f36503353f8dfd7b055e4c3b9ea2ee52180255cf4b0a + category: main + optional: false +- name: nest-asyncio + version: 1.5.8 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.5.8-pyhd8ed1ab_0.conda + hash: + md5: a4f0e4519bc50eee4f53f689be9607f7 + sha256: d7b795b4e754136841c6da3f9fa1a0f7ec37bc7167e7dd68c5b45e657133e008 + category: main + optional: false +- name: nest-asyncio + version: 1.5.8 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.5.8-pyhd8ed1ab_0.conda + hash: + md5: a4f0e4519bc50eee4f53f689be9607f7 + sha256: d7b795b4e754136841c6da3f9fa1a0f7ec37bc7167e7dd68c5b45e657133e008 + category: main + optional: false +- name: networkx + version: 3.2.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.9' + url: https://conda.anaconda.org/conda-forge/noarch/networkx-3.2.1-pyhd8ed1ab_0.conda + hash: + md5: 425fce3b531bed6ec3c74fab3e5f0a1c + sha256: 7629aa4f9f8cdff45ea7a4701fe58dccce5bf2faa01c26eb44cbb27b7e15ca9d + category: main + optional: false +- name: networkx + version: '3.2' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9' + url: https://conda.anaconda.org/conda-forge/noarch/networkx-3.2-pyhd8ed1ab_0.conda + hash: + md5: cec8cc498664cc00a070676aa89e69a7 + sha256: 3be9dc03b612dc3a52ca388d03f6eadd4f675bd244e61c13a6caafdf26e0a35d + category: main + optional: false +- name: nodeenv + version: 1.8.0 + manager: conda + platform: linux-64 + dependencies: + python: 2.7|>=3.7 + setuptools: '' + url: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.8.0-pyhd8ed1ab_0.conda + hash: + md5: 2a75b296096adabbabadd5e9782e5fcc + sha256: 1320306234552717149f36f825ddc7e27ea295f24829e9db4cc6ceaff0b032bd + category: main + optional: false +- name: nodeenv + version: 1.8.0 + manager: conda + platform: osx-arm64 + dependencies: + setuptools: '' + python: 2.7|>=3.7 + url: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.8.0-pyhd8ed1ab_0.conda + hash: + md5: 2a75b296096adabbabadd5e9782e5fcc + sha256: 1320306234552717149f36f825ddc7e27ea295f24829e9db4cc6ceaff0b032bd + category: main + optional: false +- name: nomkl + version: '1.0' + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2 + hash: + md5: 9a66894dfd07c4510beb6b3f9672ccc0 + sha256: d38542a151a90417065c1a234866f97fd1ea82a81de75ecb725955ab78f88b4b + category: main + optional: false +- name: notebook + version: 7.0.6 + manager: conda + platform: linux-64 + dependencies: + jupyter_server: '>=2.4.0,<3' + jupyterlab: '>=4.0.7,<5' + jupyterlab_server: '>=2.22.1,<3' + notebook-shim: '>=0.2,<0.3' + python: '>=3.8' + tornado: '>=6.2.0' + url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.0.6-pyhd8ed1ab_0.conda + hash: + md5: d60881c78a54cbf8042ae719f1f77a50 + sha256: 5259ad2fb47300407dafa6ea5e78085a2c8de8dcdbfbaa58592bf2677d7187a9 + category: main + optional: false +- name: notebook + version: 7.0.6 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + tornado: '>=6.2.0' + jupyter_server: '>=2.4.0,<3' + jupyterlab_server: '>=2.22.1,<3' + notebook-shim: '>=0.2,<0.3' + jupyterlab: '>=4.0.7,<5' + url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.0.6-pyhd8ed1ab_0.conda + hash: + md5: d60881c78a54cbf8042ae719f1f77a50 + sha256: 5259ad2fb47300407dafa6ea5e78085a2c8de8dcdbfbaa58592bf2677d7187a9 + category: main + optional: false +- name: notebook-shim + version: 0.2.3 + manager: conda + platform: linux-64 + dependencies: + jupyter_server: '>=1.8,<3' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.3-pyhd8ed1ab_0.conda + hash: + md5: 67e0fe74c156267d9159e9133df7fd37 + sha256: f028d7ad1f2175cde307db08b60d07e371b9d6f035cfae6c81ea94b4c408c538 + category: main + optional: false +- name: notebook-shim + version: 0.2.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + jupyter_server: '>=1.8,<3' + url: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.3-pyhd8ed1ab_0.conda + hash: + md5: 67e0fe74c156267d9159e9133df7fd37 + sha256: f028d7ad1f2175cde307db08b60d07e371b9d6f035cfae6c81ea94b4c408c538 + category: main + optional: false +- name: nspr + version: '4.35' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.35-h27087fc_0.conda + hash: + md5: da0ec11a6454ae19bff5b02ed881a2b1 + sha256: 8fadeebb2b7369a4f3b2c039a980d419f65c7b18267ba0c62588f9f894396d0c + category: main + optional: false +- name: nss + version: '3.95' + manager: conda + platform: linux-64 + dependencies: + __glibc: '>=2.17,<3.0.a0' + libgcc-ng: '>=12' + libsqlite: '>=3.44.2,<4.0a0' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + nspr: '>=4.35,<5.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/nss-3.95-h1d7d5a4_0.conda + hash: + md5: d3a8067adcc45a923f4b1987c91d69da + sha256: 02d8e38b4708ce707e51084d0dff7286e6e6d24d1bf32ebbda7710fac4a0581e + category: main + optional: false +- name: numpy + version: 1.23.5 + manager: conda + platform: linux-64 + dependencies: + libblas: '>=3.9.0,<4.0a0' + libcblas: '>=3.9.0,<4.0a0' + libgcc-ng: '>=12' + liblapack: '>=3.9.0,<4.0a0' + libstdcxx-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/numpy-1.23.5-py39h3d75532_0.conda + hash: + md5: ea5d332e361eb72c2593cf79559bc0ec + sha256: ab8c088aa07adfed0ec39ca53541b09cdf13538d7f96086f60b784cdb7ee1ff0 + category: main + optional: false +- name: numpy + version: 1.23.5 + manager: conda + platform: osx-arm64 + dependencies: + libblas: '>=3.9.0,<4.0a0' + libcblas: '>=3.9.0,<4.0a0' + libcxx: '>=14.0.6' + liblapack: '>=3.9.0,<4.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-1.23.5-py39hefdcf20_0.conda + hash: + md5: 81ebd7127e2c433bcbf98c1e45c7a583 + sha256: dc897ce874e1b45e300c94f136ed38c5efbbb9f2b21967f0b0ba404b3150614c + category: main + optional: false +- name: oauthlib + version: 3.2.2 + manager: conda + platform: linux-64 + dependencies: + blinker: '' + cryptography: '' + pyjwt: '>=1.0.0' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/oauthlib-3.2.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 8f882b197fd9c4941a787926baea4868 + sha256: 0cfd5146a91d3974f4abfc2a45de890371d510a77238fe553e036ec8c031dc5b + category: main + optional: false +- name: oauthlib + version: 3.2.2 + manager: conda + platform: osx-arm64 + dependencies: + cryptography: '' + blinker: '' + python: '>=3.6' + pyjwt: '>=1.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/oauthlib-3.2.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 8f882b197fd9c4941a787926baea4868 + sha256: 0cfd5146a91d3974f4abfc2a45de890371d510a77238fe553e036ec8c031dc5b + category: main + optional: false +- name: onnx + version: 1.14.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libprotobuf: '>=3.21.12,<3.22.0a0' + libstdcxx-ng: '>=12' + numpy: '>=1.21.6,<2.0a0' + protobuf: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + typing-extensions: '>=3.6.2.1' + url: https://conda.anaconda.org/conda-forge/linux-64/onnx-1.14.0-py39h5cf8293_1.conda + hash: + md5: f328acd6bba2c62d2751ba1821c7fa6a + sha256: a8da023239f0028f486ea5b3bbd0e96bda75ddedd56a650af3ec105a2b163209 + category: main + optional: false +- name: onnx + version: 1.14.0 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + libprotobuf: '>=3.21.12,<3.22.0a0' + numpy: '>=1.21.6,<2.0a0' + protobuf: '' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + typing-extensions: '>=3.6.2.1' + url: https://conda.anaconda.org/conda-forge/osx-arm64/onnx-1.14.0-py39h09fa150_1.conda + hash: + md5: 7408be0d67077506377d7f98fe12c211 + sha256: 5dba0d4bc4cb7cc9ab2969112c95ed85641550d7f1c5687864249f77b9b37c85 + category: main + optional: false +- name: onnxconverter-common + version: 1.13.0 + manager: conda + platform: linux-64 + dependencies: + numpy: '' + onnx: '' + packaging: '' + protobuf: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/onnxconverter-common-1.13.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: a1749e40ac6377dc5b3cde8fe683f5c9 + sha256: 8320927bbbae5f9dd4ba2abb2c046f9629111ac49ef539f537876a57af54d2ed + category: main + optional: false +- name: onnxconverter-common + version: 1.13.0 + manager: conda + platform: osx-arm64 + dependencies: + numpy: '' + packaging: '' + protobuf: '' + onnx: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/onnxconverter-common-1.13.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: a1749e40ac6377dc5b3cde8fe683f5c9 + sha256: 8320927bbbae5f9dd4ba2abb2c046f9629111ac49ef539f537876a57af54d2ed + category: main + optional: false +- name: openjpeg + version: 2.5.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libpng: '>=1.6.39,<1.7.0a0' + libstdcxx-ng: '>=12' + libtiff: '>=4.6.0,<4.7.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.0-h488ebb8_3.conda + hash: + md5: 128c25b7fe6a25286a48f3a6a9b5b6f3 + sha256: 9fe91b67289267de68fda485975bb48f0605ac503414dc663b50d8b5f29bc82a + category: main + optional: false +- name: openjpeg + version: 2.5.0 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + libpng: '>=1.6.39,<1.7.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.0-h4c1507b_3.conda + hash: + md5: 4127dd217a010d9c6cbefdaae07d9f19 + sha256: a6998c0da4643a84dc7c0b3a9e5137db258619ea922317bb7d9ae64f54b4a9ed + category: main + optional: false +- name: openssl + version: 3.1.4 + manager: conda + platform: linux-64 + dependencies: + ca-certificates: '' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.1.4-hd590300_0.conda + hash: + md5: 412ba6938c3e2abaca8b1129ea82e238 + sha256: d15b3e83ce66c6f6fbb4707f2f5c53337124c01fb03bfda1cf25c5b41123efc7 + category: main + optional: false +- name: openssl + version: 3.2.0 + manager: conda + platform: osx-arm64 + dependencies: + ca-certificates: '' + url: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.2.0-h0d3ecfb_1.conda + hash: + md5: 47d16d26100f19ca495882882b7bc93b + sha256: a53e1c6c058b621fd1d13cca6f9cccd534d2b3f4b4ac789fe26f7902031d6c41 + category: main + optional: false +- name: opt_einsum + version: 3.3.0 + manager: conda + platform: linux-64 + dependencies: + numpy: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/opt_einsum-3.3.0-pyhc1e730c_2.conda + hash: + md5: 7a94ac68b892daa9f17ae8a52b31ed81 + sha256: 1995657f10e23dbe534219f754c66b7fb2a805d68a3385abdacb7807a915b0c3 + category: main + optional: false +- name: opt_einsum + version: 3.3.0 + manager: conda + platform: osx-arm64 + dependencies: + numpy: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/opt_einsum-3.3.0-pyhc1e730c_2.conda + hash: + md5: 7a94ac68b892daa9f17ae8a52b31ed81 + sha256: 1995657f10e23dbe534219f754c66b7fb2a805d68a3385abdacb7807a915b0c3 + category: main + optional: false +- name: orc + version: 1.9.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libprotobuf: '>=3.21.12,<3.22.0a0' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + lz4-c: '>=1.9.3,<1.10.0a0' + snappy: '>=1.1.10,<2.0a0' + zstd: '>=1.5.2,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/orc-1.9.0-h2f23424_1.conda + hash: + md5: 9571eb3eb0f7fe8b59956a7786babbcd + sha256: 0948e8ce1b13f9e351df91996141fea60a0ace4d347667ed3dc59315427e0b8c + category: main + optional: false +- name: orc + version: 1.9.0 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + libprotobuf: '>=3.21.12,<3.22.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + lz4-c: '>=1.9.3,<1.10.0a0' + snappy: '>=1.1.10,<2.0a0' + zstd: '>=1.5.2,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/orc-1.9.0-ha98e9e8_1.conda + hash: + md5: 951e399cfb5abae00231ad5e4f50e933 + sha256: 908d626a5d13d79ffb056841e1dde0823caac043a2c1d9d3ca7d3f7e6de7a68c + category: main + optional: false +- name: overrides + version: 7.4.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + typing_utils: '' + url: https://conda.anaconda.org/conda-forge/noarch/overrides-7.4.0-pyhd8ed1ab_0.conda + hash: + md5: 4625b7b01d7f4ac9c96300a5515acfaa + sha256: 29db8c3b521d261bf71897ba3cfbebc81cd61e581b30fcb984b5a713f02fe1ff + category: main + optional: false +- name: overrides + version: 7.4.0 + manager: conda + platform: osx-arm64 + dependencies: + typing_utils: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/overrides-7.4.0-pyhd8ed1ab_0.conda + hash: + md5: 4625b7b01d7f4ac9c96300a5515acfaa + sha256: 29db8c3b521d261bf71897ba3cfbebc81cd61e581b30fcb984b5a713f02fe1ff + category: main + optional: false +- name: packaging + version: '23.2' + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/packaging-23.2-pyhd8ed1ab_0.conda + hash: + md5: 79002079284aa895f883c6b7f3f88fd6 + sha256: 69b3ace6cca2dab9047b2c24926077d81d236bef45329d264b394001e3c3e52f + category: main + optional: false +- name: packaging + version: '23.2' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/packaging-23.2-pyhd8ed1ab_0.conda + hash: + md5: 79002079284aa895f883c6b7f3f88fd6 + sha256: 69b3ace6cca2dab9047b2c24926077d81d236bef45329d264b394001e3c3e52f + category: main + optional: false +- name: pandas + version: 1.5.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + numpy: '>=1.20.3,<2.0a0' + python: '>=3.9,<3.10.0a0' + python-dateutil: '>=2.8.1' + python_abi: 3.9.* + pytz: '>=2020.1' + url: https://conda.anaconda.org/conda-forge/linux-64/pandas-1.5.3-py39h2ad29b5_1.conda + hash: + md5: 0d89bced73199385857310d3a648757d + sha256: ab03a569f9910c27de04ab10b8f9e5cd3481df5920ca88617aea4a761a5cf1e9 + category: main + optional: false +- name: pandas + version: 1.1.4 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=11.0.0' + numpy: '>=1.19.2,<2.0a0' + python: '>=3.9,<3.10.0a0' + python-dateutil: '>=2.7.3' + python_abi: 3.9.* + pytz: '>=2017.2' + setuptools: <60.0.0 + url: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-1.1.4-py39ha4bedbf_0.tar.bz2 + hash: + md5: c4d6ef11b9f0e4e4f7a4dac0182f74b7 + sha256: ac0a5452c67ea613d68f037d7839226f746199bbc75fc18d4105a134730df3a5 + category: main + optional: false +- name: pandera + version: 0.17.2 + manager: conda + platform: linux-64 + dependencies: + pandera-base: '>=0.17.2,<0.17.3.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/pandera-0.17.2-hd8ed1ab_1.conda + hash: + md5: 4264ebacf0a9b26d4a4201d19410f232 + sha256: 9e393ef1bcff1d2c452d18930ade00022b7da1bb1feba1d514d92b88e22b380f + category: main + optional: false +- name: pandera + version: 0.17.1 + manager: conda + platform: osx-arm64 + dependencies: + pandera-base: '>=0.17.1,<0.17.2.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/pandera-0.17.1-hd8ed1ab_1.conda + hash: + md5: fccf7b6a41d32e4326732fe4563b4f0a + sha256: 6f0a134bc48187ef5665eb577903fe58d45c32f8ace83aa55f9820535ff39ad9 + category: main + optional: false +- name: pandera-base + version: 0.17.2 + manager: conda + platform: linux-64 + dependencies: + multimethod: '' + numpy: '>=1.19.0' + packaging: '>=20.0' + pandas: '>=1.2.0' + pydantic: '' + python: '>=3.8' + typeguard: '>=3.0.2' + typing_inspect: '>=0.6.0' + wrapt: '' + url: https://conda.anaconda.org/conda-forge/noarch/pandera-base-0.17.2-pyhd8ed1ab_1.conda + hash: + md5: 66e35f81990c5929be3c39e2c1786f8c + sha256: c6057df0df40b7e3e5623d83f045d922dc6a646988466e1ea259cfd94f715963 + category: main + optional: false +- name: pandera-base + version: 0.17.1 + manager: conda + platform: osx-arm64 + dependencies: + typing_extensions: '' + wrapt: '' + multimethod: '' + python: '>=3.7' + packaging: '>=20.0' + pandas: '>=1.0' + numpy: '>=1.9.0' + typing_inspect: '>=0.6.0' + pydantic: <2.0.0 + typeguard: '>=3.0.2' + url: https://conda.anaconda.org/conda-forge/noarch/pandera-base-0.17.1-pyhd8ed1ab_0.conda + hash: + md5: f1a492b0898bd940c4c4f9909df28a8a + sha256: 55d27d7577abe4a32de46727df9ee59ff65d714d0855a0998cb4a19f6e8dbd4f + category: main + optional: false +- name: pandoc + version: 3.1.3 + manager: conda + platform: linux-64 + dependencies: + gmp: '' + libzlib: '>=1.2.13,<1.3.0a0' + zlib: '' + url: https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.1.3-h32600fe_0.conda + hash: + md5: 8287aeb8462e2d4b235eff788e75919d + sha256: 52d23e2fded05e7a19d9d7996f19ed837b46578b6e5951b8c5990cf919404ffc + category: main + optional: false +- name: pandoc + version: 3.1.3 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/pandoc-3.1.3-hce30654_0.conda + hash: + md5: 7edcc75acdac60dba441b229c0ec66ee + sha256: 858a923c8b9082791b2c13c2ff2ae87e28dd2e2655f56117c8ecb7d366002bc7 + category: main + optional: false +- name: pandocfilters + version: 1.5.0 + manager: conda + platform: linux-64 + dependencies: + python: '!=3.0,!=3.1,!=3.2,!=3.3' + url: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 457c2c8c08e54905d6954e79cb5b5db9 + sha256: 2bb9ba9857f4774b85900c2562f7e711d08dd48e2add9bee4e1612fbee27e16f + category: main + optional: false +- name: pandocfilters + version: 1.5.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '!=3.0,!=3.1,!=3.2,!=3.3' + url: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 457c2c8c08e54905d6954e79cb5b5db9 + sha256: 2bb9ba9857f4774b85900c2562f7e711d08dd48e2add9bee4e1612fbee27e16f + category: main + optional: false +- name: pango + version: 1.50.14 + manager: conda + platform: linux-64 + dependencies: + cairo: '>=1.16.0,<2.0a0' + fontconfig: '>=2.14.2,<3.0a0' + fonts-conda-ecosystem: '' + freetype: '>=2.12.1,<3.0a0' + fribidi: '>=1.0.10,<2.0a0' + harfbuzz: '>=8.1.1,<9.0a0' + libgcc-ng: '>=12' + libglib: '>=2.76.4,<3.0a0' + libpng: '>=1.6.39,<1.7.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/pango-1.50.14-ha41ecd1_2.conda + hash: + md5: 1a66c10f6a0da3dbd2f3a68127e7f6a0 + sha256: 6ecce306b7ac4acf1184eb5b045e57e613e19e99c27d57f33eb255f8a9120a93 + category: main + optional: false +- name: pango + version: 1.50.14 + manager: conda + platform: osx-arm64 + dependencies: + cairo: '>=1.16.0,<2.0a0' + fontconfig: '>=2.14.2,<3.0a0' + fonts-conda-ecosystem: '' + freetype: '>=2.12.1,<3.0a0' + fribidi: '>=1.0.10,<2.0a0' + harfbuzz: '>=8.1.1,<9.0a0' + libglib: '>=2.76.4,<3.0a0' + libpng: '>=1.6.39,<1.7.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pango-1.50.14-hcf40dda_2.conda + hash: + md5: 79026cbb74d69b444e5dc2be0fb4b4a9 + sha256: e17f649192ce06c68893b50fa2492db87d2d82ae6d3c6058cc62dcc44dde8b2e + category: main + optional: false +- name: papermill + version: 2.4.0 + manager: conda + platform: linux-64 + dependencies: + ansiwrap: '' + black: '' + click: '' + entrypoints: '' + nbclient: '>=0.2.0' + nbformat: '>=5.1.2' + python: '>=3.7' + pyyaml: '' + requests: '' + tenacity: '' + tqdm: '>=4.32.2' + url: https://conda.anaconda.org/conda-forge/noarch/papermill-2.4.0-pyhd8ed1ab_0.conda + hash: + md5: 643948c831f14c43cc4c80f302f7146e + sha256: f720b31436d8425bb21bed09a27a77d06437f4abc23da5eea0e479115ec5bf95 + category: main + optional: false +- name: papermill + version: 2.4.0 + manager: conda + platform: osx-arm64 + dependencies: + requests: '' + pyyaml: '' + click: '' + black: '' + entrypoints: '' + tenacity: '' + ansiwrap: '' + python: '>=3.7' + nbformat: '>=5.1.2' + tqdm: '>=4.32.2' + nbclient: '>=0.2.0' + url: https://conda.anaconda.org/conda-forge/noarch/papermill-2.4.0-pyhd8ed1ab_0.conda + hash: + md5: 643948c831f14c43cc4c80f302f7146e + sha256: f720b31436d8425bb21bed09a27a77d06437f4abc23da5eea0e479115ec5bf95 + category: main + optional: false +- name: paramiko + version: 3.3.1 + manager: conda + platform: linux-64 + dependencies: + bcrypt: '>=3.2' + cryptography: '>=3.3' + pynacl: '>=1.5' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/paramiko-3.3.1-pyhd8ed1ab_0.conda + hash: + md5: 8d4563992b27cdb8e673d1ca16962c9d + sha256: 9139c13cb7ea5729af862db5fb0523daa5900b9b4fa36637cd7f9c01be665f80 + category: main + optional: false +- name: paramiko + version: 3.3.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + cryptography: '>=3.3' + bcrypt: '>=3.2' + pynacl: '>=1.5' + url: https://conda.anaconda.org/conda-forge/noarch/paramiko-3.3.1-pyhd8ed1ab_0.conda + hash: + md5: 8d4563992b27cdb8e673d1ca16962c9d + sha256: 9139c13cb7ea5729af862db5fb0523daa5900b9b4fa36637cd7f9c01be665f80 + category: main + optional: false +- name: parso + version: 0.8.3 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.3-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 17a565a0c3899244e938cdf417e7b094 + sha256: 4e26d5daf5de0e31aa5e74ac56386a361b202433b83f024fdadbf07d4a244da4 + category: main + optional: false +- name: parso + version: 0.8.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.3-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 17a565a0c3899244e938cdf417e7b094 + sha256: 4e26d5daf5de0e31aa5e74ac56386a361b202433b83f024fdadbf07d4a244da4 + category: main + optional: false +- name: partd + version: 1.4.1 + manager: conda + platform: linux-64 + dependencies: + locket: '' + python: '>=3.7' + toolz: '' + url: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.1-pyhd8ed1ab_0.conda + hash: + md5: acf4b7c0bcd5fa3b0e05801c4d2accd6 + sha256: b248238da2bb9dfe98e680af911dc7013af86095e3ec8baf08905555632d34c7 + category: main + optional: false +- name: partd + version: 1.4.1 + manager: conda + platform: osx-arm64 + dependencies: + toolz: '' + locket: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.1-pyhd8ed1ab_0.conda + hash: + md5: acf4b7c0bcd5fa3b0e05801c4d2accd6 + sha256: b248238da2bb9dfe98e680af911dc7013af86095e3ec8baf08905555632d34c7 + category: main + optional: false +- name: pathspec + version: 0.11.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.11.2-pyhd8ed1ab_0.conda + hash: + md5: e41debb259e68490e3ab81e46b639ab6 + sha256: 7bcfa6d86359d45572ba9ccaeaedc04b0452e2654fe44b6fe378d0d37b8745e1 + category: main + optional: false +- name: pathspec + version: 0.11.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.11.2-pyhd8ed1ab_0.conda + hash: + md5: e41debb259e68490e3ab81e46b639ab6 + sha256: 7bcfa6d86359d45572ba9ccaeaedc04b0452e2654fe44b6fe378d0d37b8745e1 + category: main + optional: false +- name: pcre + version: '8.45' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.3.0' + libstdcxx-ng: '>=9.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/pcre-8.45-h9c3ff4c_0.tar.bz2 + hash: + md5: c05d1820a6d34ff07aaaab7a9b7eddaa + sha256: 8f35c244b1631a4f31fb1d66ab6e1d9bfac0ca9b679deced1112c7225b3ad138 + category: main + optional: false +- name: pcre + version: '8.45' + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=11.1.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pcre-8.45-hbdafb3b_0.tar.bz2 + hash: + md5: 500758f2515ae07c640d255c11afc19f + sha256: f2e0c4ae3306f94851eea2318c6d26d24f8e191e329ddd256a612cd1184c5737 + category: main + optional: false +- name: pcre2 + version: '10.42' + manager: conda + platform: linux-64 + dependencies: + bzip2: '>=1.0.8,<2.0a0' + libgcc-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.42-hcad00b1_0.conda + hash: + md5: 679c8961826aa4b50653bce17ee52abe + sha256: 3ca54ff0abcda964af7d4724d389ae20d931159ae1881cfe57ad4b0ab9e6a380 + category: main + optional: false +- name: pcre2 + version: '10.42' + manager: conda + platform: osx-arm64 + dependencies: + bzip2: '>=1.0.8,<2.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.42-h26f9a81_0.conda + hash: + md5: 3e12888ecc8ee1ebee2eef9b7856357a + sha256: 0335a08349ecd8dce0b81699fcd61b58415e658fe953feb27316fbb994df0685 + category: main + optional: false +- name: pexpect + version: 4.8.0 + manager: conda + platform: linux-64 + dependencies: + ptyprocess: '>=0.5' + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.8.0-pyh1a96a4e_2.tar.bz2 + hash: + md5: 330448ce4403cc74990ac07c555942a1 + sha256: 07706c0417ead94f359ca7278f65452d3c396448777aba1da6a11fc351bdca9a + category: main + optional: false +- name: pexpect + version: 4.8.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + ptyprocess: '>=0.5' + url: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.8.0-pyh1a96a4e_2.tar.bz2 + hash: + md5: 330448ce4403cc74990ac07c555942a1 + sha256: 07706c0417ead94f359ca7278f65452d3c396448777aba1da6a11fc351bdca9a + category: main + optional: false +- name: pickleshare + version: 0.7.5 + manager: conda + platform: linux-64 + dependencies: + python: '>=3' + url: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-py_1003.tar.bz2 + hash: + md5: 415f0ebb6198cc2801c73438a9fb5761 + sha256: a1ed1a094dd0d1b94a09ed85c283a0eb28943f2e6f22161fb45e128d35229738 + category: main + optional: false +- name: pickleshare + version: 0.7.5 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3' + url: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-py_1003.tar.bz2 + hash: + md5: 415f0ebb6198cc2801c73438a9fb5761 + sha256: a1ed1a094dd0d1b94a09ed85c283a0eb28943f2e6f22161fb45e128d35229738 + category: main + optional: false +- name: pillow + version: 10.1.0 + manager: conda + platform: linux-64 + dependencies: + freetype: '>=2.12.1,<3.0a0' + lcms2: '>=2.15,<3.0a0' + libgcc-ng: '>=12' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + libwebp-base: '>=1.3.2,<2.0a0' + libxcb: '>=1.15,<1.16.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + openjpeg: '>=2.5.0,<3.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + tk: '>=8.6.13,<8.7.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/pillow-10.1.0-py39had0adad_0.conda + hash: + md5: eeaa413fddccecb2ab7f747bdb55b07f + sha256: b474fbd1cb38a6c29372248809bbf339a2d2eff72c11601f05b19a3188dd372e + category: main + optional: false +- name: pillow + version: 10.1.0 + manager: conda + platform: osx-arm64 + dependencies: + freetype: '>=2.12.1,<3.0a0' + lcms2: '>=2.15,<3.0a0' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libtiff: '>=4.6.0,<4.7.0a0' + libwebp-base: '>=1.3.2,<2.0a0' + libxcb: '>=1.15,<1.16.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + openjpeg: '>=2.5.0,<3.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + tk: '>=8.6.13,<8.7.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pillow-10.1.0-py39h755f0b7_0.conda + hash: + md5: aa7743f5af2e30366316554982dd2e3f + sha256: 706b71b8b4eed61593ee6adaf7e52a7ae690895cd138d8b73e1f0e5ba1707bd7 + category: main + optional: false +- name: pip + version: 23.3.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + setuptools: '' + wheel: '' + url: https://conda.anaconda.org/conda-forge/noarch/pip-23.3.1-pyhd8ed1ab_0.conda + hash: + md5: 2400c0b86889f43aa52067161e1fb108 + sha256: 435829a03e1c6009f013f29bb83de8b876c388820bf8cf69a7baeec25f6a3563 + category: main + optional: false +- name: pip + version: 23.3.1 + manager: conda + platform: osx-arm64 + dependencies: + setuptools: '' + wheel: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/pip-23.3.1-pyhd8ed1ab_0.conda + hash: + md5: 2400c0b86889f43aa52067161e1fb108 + sha256: 435829a03e1c6009f013f29bb83de8b876c388820bf8cf69a7baeec25f6a3563 + category: main + optional: false +- name: pixman + version: 0.42.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.42.2-h59595ed_0.conda + hash: + md5: 700edd63ccd5fc66b70b1c028cea9a68 + sha256: ae917851474eb3b08812b02c9e945d040808523ec53f828aa74a90b0cdf15f57 + category: main + optional: false +- name: pixman + version: 0.42.2 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=15.0.7' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pixman-0.42.2-h13dd4ca_0.conda + hash: + md5: f96347021db6f33ccabe314ddeab62d4 + sha256: 90e60dc5604e356d47ef97b23b13759ef3d8b70fa2c637f4809d29851435d7d7 + category: main + optional: false +- name: pkgutil-resolve-name + version: 1.3.10 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_1.conda + hash: + md5: 405678b942f2481cecdb3e010f4925d9 + sha256: fecf95377134b0e8944762d92ecf7b0149c07d8186fb5db583125a2705c7ea0a + category: main + optional: false +- name: pkgutil-resolve-name + version: 1.3.10 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_1.conda + hash: + md5: 405678b942f2481cecdb3e010f4925d9 + sha256: fecf95377134b0e8944762d92ecf7b0149c07d8186fb5db583125a2705c7ea0a + category: main + optional: false +- name: platformdirs + version: 3.8.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + typing-extensions: '>=4.6.3' + url: https://conda.anaconda.org/conda-forge/noarch/platformdirs-3.8.1-pyhd8ed1ab_0.conda + hash: + md5: e76070baecfaca6ecdb5fbd5af7c9309 + sha256: b5012d6fd30f2462b6ca595539cfdae9aaf61b3b7a56e51ab94aef0fd9efcd3d + category: main + optional: false +- name: platformdirs + version: 3.8.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + typing-extensions: '>=4.6.3' + url: https://conda.anaconda.org/conda-forge/noarch/platformdirs-3.8.1-pyhd8ed1ab_0.conda + hash: + md5: e76070baecfaca6ecdb5fbd5af7c9309 + sha256: b5012d6fd30f2462b6ca595539cfdae9aaf61b3b7a56e51ab94aef0fd9efcd3d + category: main + optional: false +- name: plotly + version: 5.18.0 + manager: conda + platform: linux-64 + dependencies: + packaging: '' + python: '>=3.6' + tenacity: '>=6.2.0' + url: https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda + hash: + md5: 9f6a8664f1fe752f79473eeb9bf33a60 + sha256: 1e812d896897a4d58d520bb51072d91d477faf7697e2b724b8ce59040989e8be + category: main + optional: false +- name: plotly + version: 5.18.0 + manager: conda + platform: osx-arm64 + dependencies: + packaging: '' + python: '>=3.6' + tenacity: '>=6.2.0' + url: https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda + hash: + md5: 9f6a8664f1fe752f79473eeb9bf33a60 + sha256: 1e812d896897a4d58d520bb51072d91d477faf7697e2b724b8ce59040989e8be + category: main + optional: false +- name: polars + version: 0.19.19 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + numpy: '>=1.16.0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + typing_extensions: '>=4.0.0' + url: https://conda.anaconda.org/conda-forge/linux-64/polars-0.19.19-py39h90d8ae4_0.conda + hash: + md5: 9cefe0d7ce9208c3afbbac29951aff59 + sha256: 862ab4acd653e75da36a371c5c50fdb295b28b07d496b54b3d0f908858639968 + category: main + optional: false +- name: polars + version: 0.19.19 + manager: conda + platform: osx-arm64 + dependencies: + numpy: '>=1.16.0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + typing_extensions: '>=4.0.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/polars-0.19.19-py39hf9b72a1_0.conda + hash: + md5: 64dc65feee192e9e9e9312ed63ba0460 + sha256: 5978bd41bda03050fe9578e3950afd746cf6473d6efc31d50892b76d1dd7b919 + category: main + optional: false +- name: poppler + version: 23.11.0 + manager: conda + platform: linux-64 + dependencies: + cairo: '>=1.18.0,<2.0a0' + fontconfig: '>=2.14.2,<3.0a0' + fonts-conda-ecosystem: '' + freetype: '>=2.12.1,<3.0a0' + lcms2: '>=2.15,<3.0a0' + libcurl: '>=8.4.0,<9.0a0' + libgcc-ng: '>=12' + libglib: '>=2.78.0,<3.0a0' + libiconv: '>=1.17,<2.0a0' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libstdcxx-ng: '>=12' + libtiff: '>=4.6.0,<4.7.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + nspr: '>=4.35,<5.0a0' + nss: '>=3.94,<4.0a0' + openjpeg: '>=2.5.0,<3.0a0' + poppler-data: '' + url: https://conda.anaconda.org/conda-forge/linux-64/poppler-23.11.0-h590f24d_0.conda + hash: + md5: 671439d8eca2084bb5a75561fff23a85 + sha256: 8050002e01be124efcb82e32e740676f5ed7dfe852f335408554e6dc3b060ad9 + category: main + optional: false +- name: poppler-data + version: 0.4.12 + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda + hash: + md5: d8d7293c5b37f39b2ac32940621c6592 + sha256: 2f227e17b3c0346112815faa605502b66c1c4511a856127f2899abf15a98a2cf + category: main + optional: false +- name: portalocker + version: 2.8.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/portalocker-2.8.2-py39hf3d152e_1.conda + hash: + md5: 4b8a715013375a33ad87a4e118f807d7 + sha256: 7b78075d514c602946a36df7604630c058b80a7378f7d0e29e4a082031fde19b + category: main + optional: false +- name: portalocker + version: 2.8.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/portalocker-2.8.2-py39h2804cbe_1.conda + hash: + md5: 736dc8a89a32fc01cf27ec6ba6a97bb7 + sha256: 1a278be7e08c397516a529e7b7fa866867a5551cb3d5feb8f222581f36d8300f + category: main + optional: false +- name: postgresql + version: '16.1' + manager: conda + platform: linux-64 + dependencies: + krb5: '>=1.21.2,<1.22.0a0' + libgcc-ng: '>=12' + libpq: '16.1' + libxml2: '>=2.11.5,<2.12.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + openssl: '>=3.1.4,<4.0a0' + readline: '>=8.2,<9.0a0' + tzcode: '' + tzdata: '' + zlib: '' + url: https://conda.anaconda.org/conda-forge/linux-64/postgresql-16.1-h8972f4a_0.conda + hash: + md5: 1e9ab0760262044fa00814088667e451 + sha256: 74dfb5793a00a0a9e85296ce0944d8af0f71758574b7c8f9e7d5590250441e24 + category: main + optional: false +- name: pre-commit + version: 3.5.0 + manager: conda + platform: linux-64 + dependencies: + cfgv: '>=2.0.0' + identify: '>=1.0.0' + nodeenv: '>=0.11.1' + python: '>=3.8' + pyyaml: '>=5.1' + virtualenv: '>=20.10.0' + url: https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.5.0-pyha770c72_0.conda + hash: + md5: 964e3d762e427661c59263435a14c492 + sha256: 51a4a17334a15ec92805cd075776563ff93b3b6c20732c4cb607c98a761ae02f + category: main + optional: false +- name: pre-commit + version: 3.5.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + pyyaml: '>=5.1' + identify: '>=1.0.0' + nodeenv: '>=0.11.1' + cfgv: '>=2.0.0' + virtualenv: '>=20.10.0' + url: https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.5.0-pyha770c72_0.conda + hash: + md5: 964e3d762e427661c59263435a14c492 + sha256: 51a4a17334a15ec92805cd075776563ff93b3b6c20732c4cb607c98a761ae02f + category: main + optional: false +- name: progressbar2 + version: 4.2.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + python-utils: '>=3.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/progressbar2-4.2.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: d883564cf1e9ba190f6b285036c5f949 + sha256: c7a0307fbe83694f84c4024b176aaa484be9277ba5fde82e24a02bc72f24a53f + category: main + optional: false +- name: progressbar2 + version: 4.2.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + python-utils: '>=3.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/progressbar2-4.2.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: d883564cf1e9ba190f6b285036c5f949 + sha256: c7a0307fbe83694f84c4024b176aaa484be9277ba5fde82e24a02bc72f24a53f + category: main + optional: false +- name: proj + version: 9.3.0 + manager: conda + platform: linux-64 + dependencies: + libcurl: '>=8.4.0,<9.0a0' + libgcc-ng: '>=12' + libsqlite: '>=3.43.2,<4.0a0' + libstdcxx-ng: '>=12' + libtiff: '>=4.6.0,<4.7.0a0' + sqlite: '' + url: https://conda.anaconda.org/conda-forge/linux-64/proj-9.3.0-h1d62c97_2.conda + hash: + md5: b5e57a0c643da391bef850922963eece + sha256: 252f6c31101719e3d524679e69ae81e6323b93b143e1360169bf50e89386bf24 + category: main + optional: false +- name: prometheus_client + version: 0.19.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.19.0-pyhd8ed1ab_0.conda + hash: + md5: 7baa10fa8073c371155cf451b71b848d + sha256: 1235a3dbb033f914163e0deaf22d244cb1c1b5d8829d0089e38c34079286acbe + category: main + optional: false +- name: prometheus_client + version: 0.19.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.19.0-pyhd8ed1ab_0.conda + hash: + md5: 7baa10fa8073c371155cf451b71b848d + sha256: 1235a3dbb033f914163e0deaf22d244cb1c1b5d8829d0089e38c34079286acbe + category: main + optional: false +- name: prometheus_flask_exporter + version: 0.23.0 + manager: conda + platform: linux-64 + dependencies: + flask: '' + prometheus_client: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/prometheus_flask_exporter-0.23.0-pyhd8ed1ab_0.conda + hash: + md5: bff3dd780880d653865a542dc13741ed + sha256: 6601b7520b3c18d07d2ef8086377c1af8ef85fcbd9122d786a69494585b31235 + category: main + optional: false +- name: prometheus_flask_exporter + version: 0.23.0 + manager: conda + platform: osx-arm64 + dependencies: + flask: '' + prometheus_client: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/prometheus_flask_exporter-0.23.0-pyhd8ed1ab_0.conda + hash: + md5: bff3dd780880d653865a542dc13741ed + sha256: 6601b7520b3c18d07d2ef8086377c1af8ef85fcbd9122d786a69494585b31235 + category: main + optional: false +- name: prompt-toolkit + version: 3.0.41 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + wcwidth: '' + url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.41-pyha770c72_0.conda + hash: + md5: f511a993aa4336bef9dd874ee3403e67 + sha256: e26a5554883a0eada3641b6d861d8cb4895e2c7fcc17a587de07b8b1ecbfff0f + category: main + optional: false +- name: prompt-toolkit + version: 3.0.41 + manager: conda + platform: osx-arm64 + dependencies: + wcwidth: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.41-pyha770c72_0.conda + hash: + md5: f511a993aa4336bef9dd874ee3403e67 + sha256: e26a5554883a0eada3641b6d861d8cb4895e2c7fcc17a587de07b8b1ecbfff0f + category: main + optional: false +- name: prompt_toolkit + version: 3.0.41 + manager: conda + platform: linux-64 + dependencies: + prompt-toolkit: '>=3.0.41,<3.0.42.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.41-hd8ed1ab_0.conda + hash: + md5: b1387bd091fa0420557f801a78587678 + sha256: dd2fea25930d258159441ad4a45e5d3274f0d2f1dea92fe25b44b48c486aa969 + category: main + optional: false +- name: prompt_toolkit + version: 3.0.41 + manager: conda + platform: osx-arm64 + dependencies: + prompt-toolkit: '>=3.0.41,<3.0.42.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.41-hd8ed1ab_0.conda + hash: + md5: b1387bd091fa0420557f801a78587678 + sha256: dd2fea25930d258159441ad4a45e5d3274f0d2f1dea92fe25b44b48c486aa969 + category: main + optional: false +- name: proto-plus + version: 1.22.3 + manager: conda + platform: linux-64 + dependencies: + protobuf: '>=3.19.0,<5.0.0dev' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/proto-plus-1.22.3-pyhd8ed1ab_0.conda + hash: + md5: 5accead0a4f3b2287e1ae1992f7b614f + sha256: f697e596b53f2c500301743ad57d7c56ed3d7902c5cf027178cb2de0bf41c6ca + category: main + optional: false +- name: proto-plus + version: 1.22.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + protobuf: '>=3.19.0,<5.0.0dev' + url: https://conda.anaconda.org/conda-forge/noarch/proto-plus-1.22.3-pyhd8ed1ab_0.conda + hash: + md5: 5accead0a4f3b2287e1ae1992f7b614f + sha256: f697e596b53f2c500301743ad57d7c56ed3d7902c5cf027178cb2de0bf41c6ca + category: main + optional: false +- name: protobuf + version: 4.21.12 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libprotobuf: '>=3.21.12,<3.22.0a0' + libstdcxx-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + setuptools: '' + url: https://conda.anaconda.org/conda-forge/linux-64/protobuf-4.21.12-py39h227be39_0.conda + hash: + md5: 984b4ee0c3241d7ce715f8a731421073 + sha256: 22c02a0ae705170d169642056ce2cdf17a9c64b394dc24ed5133e9761bd4486f + category: main + optional: false +- name: protobuf + version: 4.21.12 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=14.0.6' + libprotobuf: '>=3.21.12,<3.22.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + setuptools: '' + url: https://conda.anaconda.org/conda-forge/osx-arm64/protobuf-4.21.12-py39h23fbdae_0.conda + hash: + md5: 0b221c03b2823acffb6365b8cc31e887 + sha256: 54929bb589a9273e62eeefc1d2940716d1c3465b375222cd00e4b510d2844a3b + category: main + optional: false +- name: protoc-gen-swagger + version: 0.1.0 + manager: conda + platform: linux-64 + dependencies: + protobuf: '>=3.0.0' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/protoc-gen-swagger-0.1.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: cb19a2a0c0ea68f9d316792a60965c82 + sha256: e12577e09de098d0e3468ba82815bd411ebad4fac644430d283ea867193d55e6 + category: main + optional: false +- name: protoc-gen-swagger + version: 0.1.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + protobuf: '>=3.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/protoc-gen-swagger-0.1.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: cb19a2a0c0ea68f9d316792a60965c82 + sha256: e12577e09de098d0e3468ba82815bd411ebad4fac644430d283ea867193d55e6 + category: main + optional: false +- name: psutil + version: 5.9.5 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/psutil-5.9.5-py39hd1e30aa_1.conda + hash: + md5: c2e412b0f11e5983bcfc35d9beb91ecb + sha256: 02df40691ebe8632ad18ca641c70b74302b538922ccc86c3afee5de83f4298f0 + category: main + optional: false +- name: psutil + version: 5.9.5 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-5.9.5-py39h0f82c59_1.conda + hash: + md5: 1eb70daf1eb8478c5ccccf680a2dc025 + sha256: de53e5cd7ab4e14a957fcba7fa467beca916e4461f621f32a77dce331b95237c + category: main + optional: false +- name: psycopg2 + version: 2.9.9 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libpq: '>=16.1,<17.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/psycopg2-2.9.9-py39h89197e3_0.conda + hash: + md5: f4f1743bb5a3b5ecc4716abf3f7d3b0a + sha256: 717e8791ee5281e8c8051134a4c6597d9e54f47686aa02dc3210af089e2ac3b3 + category: main + optional: false +- name: psycopg2 + version: 2.9.9 + manager: conda + platform: osx-arm64 + dependencies: + libpq: '>=16.1,<17.0a0' + openssl: '>=3.2.0,<4.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/psycopg2-2.9.9-py39h78886fb_0.conda + hash: + md5: eca4680f46c9db00a80ce6860cd878ff + sha256: e84b74dad7be25116b920da3ff9534c953e7336d9f8de57f1d6c681bf9abc1e8 + category: main + optional: false +- name: psycopg2-binary + version: 2.9.9 + manager: conda + platform: linux-64 + dependencies: + psycopg2: '>=2.9.9,<2.9.10.0a0' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/psycopg2-binary-2.9.9-pyhd8ed1ab_0.conda + hash: + md5: c15b2ec0570f8988819eea58286dbc19 + sha256: bb6184a3de8a6fddaed9104539ada9ac7c5e2bd900284ccf96ef5e4e285e75db + category: main + optional: false +- name: psycopg2-binary + version: 2.9.9 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + psycopg2: '>=2.9.9,<2.9.10.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/psycopg2-binary-2.9.9-pyhd8ed1ab_0.conda + hash: + md5: c15b2ec0570f8988819eea58286dbc19 + sha256: bb6184a3de8a6fddaed9104539ada9ac7c5e2bd900284ccf96ef5e4e285e75db + category: main + optional: false +- name: pthread-stubs + version: '0.4' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=7.5.0' + url: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-h36c2ea0_1001.tar.bz2 + hash: + md5: 22dad4df6e8630e8dff2428f6f6a7036 + sha256: 67c84822f87b641d89df09758da498b2d4558d47b920fd1d3fe6d3a871e000ff + category: main + optional: false +- name: pthread-stubs + version: '0.4' + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-h27ca646_1001.tar.bz2 + hash: + md5: d3f26c6494d4105d4ecb85203d687102 + sha256: 9da9e6f5d51dff6ad2e4ee0874791437ba952e0a6249942273f0fedfd07ea826 + category: main + optional: false +- name: ptyprocess + version: 0.7.0 + manager: conda + platform: linux-64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 + hash: + md5: 359eeb6536da0e687af562ed265ec263 + sha256: fb31e006a25eb2e18f3440eb8d17be44c8ccfae559499199f73584566d0a444a + category: main + optional: false +- name: ptyprocess + version: 0.7.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 + hash: + md5: 359eeb6536da0e687af562ed265ec263 + sha256: fb31e006a25eb2e18f3440eb8d17be44c8ccfae559499199f73584566d0a444a + category: main + optional: false +- name: pure_eval + version: 0.2.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 6784285c7e55cb7212efabc79e4c2883 + sha256: 72792f9fc2b1820e37cc57f84a27bc819c71088c3002ca6db05a2e56404f9d44 + category: main + optional: false +- name: pure_eval + version: 0.2.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 6784285c7e55cb7212efabc79e4c2883 + sha256: 72792f9fc2b1820e37cc57f84a27bc819c71088c3002ca6db05a2e56404f9d44 + category: main + optional: false +- name: py + version: 1.11.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/py-1.11.0-pyh6c4a22f_0.tar.bz2 + hash: + md5: b4613d7e7a493916d867842a6a148054 + sha256: 268be33a290e3d51467ab29cbb5a80cf79f69dade2f2dead25d7f80d76c3543a + category: main + optional: false +- name: py + version: 1.11.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/py-1.11.0-pyh6c4a22f_0.tar.bz2 + hash: + md5: b4613d7e7a493916d867842a6a148054 + sha256: 268be33a290e3d51467ab29cbb5a80cf79f69dade2f2dead25d7f80d76c3543a + category: main + optional: false +- name: py4j + version: 0.10.9.7 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/py4j-0.10.9.7-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 0f01a52cf858aef86632a8ab08011c0c + sha256: 5a1d134f58dbc2c77b7985069a5485fe4aa09d49f1b545087913af62559ff738 + category: main + optional: false +- name: py4j + version: 0.10.9.7 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/py4j-0.10.9.7-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 0f01a52cf858aef86632a8ab08011c0c + sha256: 5a1d134f58dbc2c77b7985069a5485fe4aa09d49f1b545087913af62559ff738 + category: main + optional: false +- name: pyarrow + version: 12.0.1 + manager: conda + platform: linux-64 + dependencies: + libarrow: 12.0.1 + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + numpy: '>=1.21.6,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.1-py39hfbd5978_8_cpu.conda + hash: + md5: fd98f7cc88572cff805a9576c8448c65 + sha256: 36036e1b71b85b218b542f996ddf8b25e8d4dd0411855c9bfad21f79d7dfac36 + category: main + optional: false +- name: pyarrow + version: 12.0.1 + manager: conda + platform: osx-arm64 + dependencies: + libarrow: 12.0.1 + libcxx: '>=15.0.7' + numpy: '>=1.21.6,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-12.0.1-py39hf40061a_8_cpu.conda + hash: + md5: 63896ce85b0d0afd38363fdb00e10d9f + sha256: d469979b28263e75fb7c64fdee8878ab02dff0d246004573e11b9bdb301856a4 + category: main + optional: false +- name: pyarrow-hotfix + version: '0.6' + manager: conda + platform: linux-64 + dependencies: + pyarrow: '>=0.14' + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda + hash: + md5: ccc06e6ef2064ae129fab3286299abda + sha256: 9b767969d059c106aac6596438a7e7ebd3aa1e2ff6553d4b7e05126dfebf4bd6 + category: main + optional: false +- name: pyarrow-hotfix + version: '0.6' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + pyarrow: '>=0.14' + url: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda + hash: + md5: ccc06e6ef2064ae129fab3286299abda + sha256: 9b767969d059c106aac6596438a7e7ebd3aa1e2ff6553d4b7e05126dfebf4bd6 + category: main + optional: false +- name: pyasn1 + version: 0.5.1 + manager: conda + platform: linux-64 + dependencies: + python: '!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,!=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/pyasn1-0.5.1-pyhd8ed1ab_0.conda + hash: + md5: fb1a800972b072aa4d16450983c81418 + sha256: 8b116da9acbb471e107203c11acaffcb259aca2367aa7e83e796e43ed5d381b3 + category: main + optional: false +- name: pyasn1 + version: 0.5.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,!=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/pyasn1-0.5.1-pyhd8ed1ab_0.conda + hash: + md5: fb1a800972b072aa4d16450983c81418 + sha256: 8b116da9acbb471e107203c11acaffcb259aca2367aa7e83e796e43ed5d381b3 + category: main + optional: false +- name: pyasn1-modules + version: 0.3.0 + manager: conda + platform: linux-64 + dependencies: + pyasn1: '>=0.4.6,<0.6.0' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/pyasn1-modules-0.3.0-pyhd8ed1ab_0.conda + hash: + md5: 26db749166cdca55e5ef1ffdc7767d0e + sha256: 7867ba43b6ef1e66054ca6b70f59bbef4cdb0cc761f0be3b66d79d15bd43143b + category: main + optional: false +- name: pyasn1-modules + version: 0.3.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + pyasn1: '>=0.4.6,<0.6.0' + url: https://conda.anaconda.org/conda-forge/noarch/pyasn1-modules-0.3.0-pyhd8ed1ab_0.conda + hash: + md5: 26db749166cdca55e5ef1ffdc7767d0e + sha256: 7867ba43b6ef1e66054ca6b70f59bbef4cdb0cc761f0be3b66d79d15bd43143b + category: main + optional: false +- name: pycparser + version: '2.21' + manager: conda + platform: linux-64 + dependencies: + python: 2.7.*|>=3.4 + url: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.21-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 076becd9e05608f8dc72757d5f3a91ff + sha256: 74c63fd03f1f1ea2b54e8bc529fd1a600aaafb24027b738d0db87909ee3a33dc + category: main + optional: false +- name: pycparser + version: '2.21' + manager: conda + platform: osx-arm64 + dependencies: + python: 2.7.*|>=3.4 + url: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.21-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 076becd9e05608f8dc72757d5f3a91ff + sha256: 74c63fd03f1f1ea2b54e8bc529fd1a600aaafb24027b738d0db87909ee3a33dc + category: main + optional: false +- name: pydantic + version: 1.10.13 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + typing-extensions: '>=4.2.0' + url: https://conda.anaconda.org/conda-forge/linux-64/pydantic-1.10.13-py39hd1e30aa_1.conda + hash: + md5: f3d35e3b6357598fae3a7e81aa36385f + sha256: b3ad6cccfe0c710d6fcb6b24c54255c924bfc52b83af13e296b0d7198546c08f + category: main + optional: false +- name: pydantic + version: 1.10.13 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + typing-extensions: '>=4.2.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-1.10.13-py39h17cfd9d_1.conda + hash: + md5: b6fb4bfeba3f13f52939e2e40efaf5f8 + sha256: 0bf6688875f926de77eeebe7a3507f89f2cd70263abf8bc609876d2601ed21a0 + category: main + optional: false +- name: pygments + version: 2.17.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/pygments-2.17.2-pyhd8ed1ab_0.conda + hash: + md5: 140a7f159396547e9799aa98f9f0742e + sha256: af5f8867450dc292f98ea387d4d8945fc574284677c8f60eaa9846ede7387257 + category: main + optional: false +- name: pygments + version: 2.17.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/pygments-2.17.2-pyhd8ed1ab_0.conda + hash: + md5: 140a7f159396547e9799aa98f9f0742e + sha256: af5f8867450dc292f98ea387d4d8945fc574284677c8f60eaa9846ede7387257 + category: main + optional: false +- name: pyjwt + version: 2.8.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/pyjwt-2.8.0-pyhd8ed1ab_0.conda + hash: + md5: 912c0194f898fdb783021fd25f913c31 + sha256: 88ac94c42ade15113397e30d1831dd341399b5262fb5330b9240f915c33cd232 + category: main + optional: false +- name: pyjwt + version: 2.8.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/pyjwt-2.8.0-pyhd8ed1ab_0.conda + hash: + md5: 912c0194f898fdb783021fd25f913c31 + sha256: 88ac94c42ade15113397e30d1831dd341399b5262fb5330b9240f915c33cd232 + category: main + optional: false +- name: pynacl + version: 1.5.0 + manager: conda + platform: linux-64 + dependencies: + cffi: '>=1.4.1' + libgcc-ng: '>=12' + libsodium: '>=1.0.18,<1.0.19.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + six: '' + url: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.5.0-py39hd1e30aa_3.conda + hash: + md5: b7595c0ba694ee1b6cca8d6e76d9f3f8 + sha256: 92ab9febd08bf59bd21ca851829b7af075b9b182aecc54e025fcbad620034897 + category: main + optional: false +- name: pynacl + version: 1.5.0 + manager: conda + platform: osx-arm64 + dependencies: + cffi: '>=1.4.1' + libsodium: '>=1.0.18,<1.0.19.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + six: '' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.5.0-py39h0f82c59_3.conda + hash: + md5: 70bfc1adb7677ec2ab7b97789acd0ba6 + sha256: 5113a7fbf60125c02f7c624f92caee30962e967bb6e57b7cb6fd730ba4f04d2c + category: main + optional: false +- name: pyobjc-core + version: '10.0' + manager: conda + platform: osx-arm64 + dependencies: + libffi: '>=3.4,<4.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + setuptools: '' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-10.0-py39h4d1a642_0.conda + hash: + md5: b43580f935baa5ff17efa249372eaa8c + sha256: 77ffc64e521e2615041dd6a9d2828c02dddd36b109668e3e8735d3c96f3cf27b + category: main + optional: false +- name: pyobjc-framework-cocoa + version: '10.0' + manager: conda + platform: osx-arm64 + dependencies: + libffi: '>=3.4,<4.0a0' + pyobjc-core: 10.0.* + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-10.0-py39h4d1a642_1.conda + hash: + md5: 75df2ac716a9c2d1bbd17113959538e4 + sha256: 89a67bed1a1261321e533159ec8b89e8a47f3cba74e6f10ff0989bcca116b209 + category: main + optional: false +- name: pyopenssl + version: 23.3.0 + manager: conda + platform: linux-64 + dependencies: + cryptography: '>=41.0.5,<42' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/pyopenssl-23.3.0-pyhd8ed1ab_0.conda + hash: + md5: 7819533e674dbbc51468f3228b9b1bb6 + sha256: f7e04c4a49b1593140231d70801e2204e314e26d7141bfbdc8089d04114c0010 + category: main + optional: false +- name: pyopenssl + version: 23.3.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + cryptography: '>=41.0.5,<42' + url: https://conda.anaconda.org/conda-forge/noarch/pyopenssl-23.3.0-pyhd8ed1ab_0.conda + hash: + md5: 7819533e674dbbc51468f3228b9b1bb6 + sha256: f7e04c4a49b1593140231d70801e2204e314e26d7141bfbdc8089d04114c0010 + category: main + optional: false +- name: pyparsing + version: 3.1.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.1-pyhd8ed1ab_0.conda + hash: + md5: 176f7d56f0cfe9008bdf1bccd7de02fb + sha256: 4a1332d634b6c2501a973655d68f08c9c42c0bd509c349239127b10572b8354b + category: main + optional: false +- name: pyparsing + version: 3.1.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.1-pyhd8ed1ab_0.conda + hash: + md5: 176f7d56f0cfe9008bdf1bccd7de02fb + sha256: 4a1332d634b6c2501a973655d68f08c9c42c0bd509c349239127b10572b8354b + category: main + optional: false +- name: pyproj + version: 3.6.1 + manager: conda + platform: linux-64 + dependencies: + certifi: '' + libgcc-ng: '>=12' + proj: '>=9.3.0,<9.3.1.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/pyproj-3.6.1-py39hce394fd_4.conda + hash: + md5: 4b6e79000ec3a495f429b2c1092ed63b + sha256: b1507e9ce71b6513b44c4c16cd8a99c456fda34e187f57dd34c23e72b9c55127 + category: main + optional: false +- name: pysocks + version: 1.7.1 + manager: conda + platform: linux-64 + dependencies: + __unix: '' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2 + hash: + md5: 2a7de29fb590ca14b5243c4c812c8025 + sha256: a42f826e958a8d22e65b3394f437af7332610e43ee313393d1cf143f0a2d274b + category: main + optional: false +- name: pysocks + version: 1.7.1 + manager: conda + platform: osx-arm64 + dependencies: + __unix: '' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2 + hash: + md5: 2a7de29fb590ca14b5243c4c812c8025 + sha256: a42f826e958a8d22e65b3394f437af7332610e43ee313393d1cf143f0a2d274b + category: main + optional: false +- name: pyspark + version: 3.5.0 + manager: conda + platform: linux-64 + dependencies: + numpy: '>=1.15' + pandas: '>=1.0.5' + py4j: 0.10.9.7 + pyarrow: '>=4.0.0' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/pyspark-3.5.0-pyhd8ed1ab_0.conda + hash: + md5: 3b21d41045c94f1ec76c16f50f25810d + sha256: daa2b0033aaf53d0c6745090f42d45304afac699de1ca7874b7978578bd2329e + category: main + optional: false +- name: pyspark + version: 3.5.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + numpy: '>=1.15' + pandas: '>=1.0.5' + pyarrow: '>=4.0.0' + py4j: 0.10.9.7 + url: https://conda.anaconda.org/conda-forge/noarch/pyspark-3.5.0-pyhd8ed1ab_0.conda + hash: + md5: 3b21d41045c94f1ec76c16f50f25810d + sha256: daa2b0033aaf53d0c6745090f42d45304afac699de1ca7874b7978578bd2329e + category: main + optional: false +- name: python + version: 3.9.18 + manager: conda + platform: linux-64 + dependencies: + bzip2: '>=1.0.8,<2.0a0' + ld_impl_linux-64: '>=2.36.1' + libffi: '>=3.4,<4.0a0' + libgcc-ng: '>=12' + libnsl: '>=2.0.0,<2.1.0a0' + libsqlite: '>=3.43.0,<4.0a0' + libuuid: '>=2.38.1,<3.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + ncurses: '>=6.4,<7.0a0' + openssl: '>=3.1.2,<4.0a0' + readline: '>=8.2,<9.0a0' + tk: '>=8.6.12,<8.7.0a0' + tzdata: '' + xz: '>=5.2.6,<6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/python-3.9.18-h0755675_0_cpython.conda + hash: + md5: 3ede353bc605068d9677e700b1847382 + sha256: 18db2220328abee8eb19f51c8df88bcfdf3a557b8181e7f5bda291deb067e40f + category: main + optional: false +- name: python + version: 3.9.18 + manager: conda + platform: osx-arm64 + dependencies: + bzip2: '>=1.0.8,<2.0a0' + libffi: '>=3.4,<4.0a0' + libsqlite: '>=3.43.0,<4.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + ncurses: '>=6.4,<7.0a0' + openssl: '>=3.1.2,<4.0a0' + readline: '>=8.2,<9.0a0' + tk: '>=8.6.12,<8.7.0a0' + tzdata: '' + xz: '>=5.2.6,<6.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.9.18-hfa1ae8a_0_cpython.conda + hash: + md5: 7672472bbab6419a1211403e7c041116 + sha256: d6a4c49354b73248741b8b8cbfb0516ef6ceb3d6b3a4d110946195c7df228672 + category: main + optional: false +- name: python-dateutil + version: 2.8.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + six: '>=1.5' + url: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.8.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: dd999d1cc9f79e67dbb855c8924c7984 + sha256: 54d7785c7678166aa45adeaccfc1d2b8c3c799ca2dc05d4a82bb39b1968bd7da + category: main + optional: false +- name: python-dateutil + version: 2.8.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + six: '>=1.5' + url: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.8.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: dd999d1cc9f79e67dbb855c8924c7984 + sha256: 54d7785c7678166aa45adeaccfc1d2b8c3c799ca2dc05d4a82bb39b1968bd7da + category: main + optional: false +- name: python-fastjsonschema + version: 2.19.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.3' + url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.0-pyhd8ed1ab_0.conda + hash: + md5: e4dbdb3585c0266b4710467fe7b75cf4 + sha256: fdfe3f387c5ebde803605e1e90871c424519d2bfe2eb3bf9caad1c5a07f4c462 + category: main + optional: false +- name: python-fastjsonschema + version: 2.19.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.3' + url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.0-pyhd8ed1ab_0.conda + hash: + md5: e4dbdb3585c0266b4710467fe7b75cf4 + sha256: fdfe3f387c5ebde803605e1e90871c424519d2bfe2eb3bf9caad1c5a07f4c462 + category: main + optional: false +- name: python-flatbuffers + version: 23.5.26 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/python-flatbuffers-23.5.26-pyhd8ed1ab_0.conda + hash: + md5: 131dd3656f3b731ab852fc66d3c41058 + sha256: 6d2fdc92fce4124e2d32403b71da89e9f3e65393670d74466b4ff4843434392e + category: main + optional: false +- name: python-flatbuffers + version: 23.5.26 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/python-flatbuffers-23.5.26-pyhd8ed1ab_0.conda + hash: + md5: 131dd3656f3b731ab852fc66d3c41058 + sha256: 6d2fdc92fce4124e2d32403b71da89e9f3e65393670d74466b4ff4843434392e + category: main + optional: false +- name: python-json-logger + version: 2.0.7 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda + hash: + md5: a61bf9ec79426938ff785eb69dbb1960 + sha256: 4790787fe1f4e8da616edca4acf6a4f8ed4e7c6967aa31b920208fc8f95efcca + category: main + optional: false +- name: python-json-logger + version: 2.0.7 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda + hash: + md5: a61bf9ec79426938ff785eb69dbb1960 + sha256: 4790787fe1f4e8da616edca4acf6a4f8ed4e7c6967aa31b920208fc8f95efcca + category: main + optional: false +- name: python-kubernetes + version: 28.1.0 + manager: conda + platform: linux-64 + dependencies: + certifi: '>=14.05.14' + google-auth: '>=1.0.1' + oauthlib: '>=3.2.2' + python: '>=3.6' + python-dateutil: '>=2.5.3' + pyyaml: '>=5.4.1' + requests: '' + requests-oauthlib: '' + six: '>=1.9.0' + urllib3: '>=1.24.2,<2.0' + websocket-client: '>=0.32.0,!=0.40.0,!=0.41.*,!=0.42.*' + url: https://conda.anaconda.org/conda-forge/noarch/python-kubernetes-28.1.0-pyhd8ed1ab_0.conda + hash: + md5: 19e0767d01e052487650c0341c186219 + sha256: 559098188048ea52739815b2311b06bf381bf4c7a7924baaf2e99de0c01b2113 + category: main + optional: false +- name: python-kubernetes + version: 28.1.0 + manager: conda + platform: osx-arm64 + dependencies: + requests: '' + requests-oauthlib: '' + python: '>=3.6' + six: '>=1.9.0' + pyyaml: '>=5.4.1' + python-dateutil: '>=2.5.3' + certifi: '>=14.05.14' + google-auth: '>=1.0.1' + websocket-client: '>=0.32.0,!=0.40.0,!=0.41.*,!=0.42.*' + oauthlib: '>=3.2.2' + urllib3: '>=1.24.2,<2.0' + url: https://conda.anaconda.org/conda-forge/noarch/python-kubernetes-28.1.0-pyhd8ed1ab_0.conda + hash: + md5: 19e0767d01e052487650c0341c186219 + sha256: 559098188048ea52739815b2311b06bf381bf4c7a7924baaf2e99de0c01b2113 + category: main + optional: false +- name: python-slugify + version: 8.0.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + text-unidecode: '>=1.3' + url: https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.1-pyhd8ed1ab_2.conda + hash: + md5: 519897ff446e0dc056e12402e6785cd5 + sha256: 68ac5a6a467b9c0a98e326ec4cc8e3c01d4514f1200c1b44102923424e8ed1eb + category: main + optional: false +- name: python-slugify + version: 8.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + text-unidecode: '>=1.3' + url: https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.1-pyhd8ed1ab_2.conda + hash: + md5: 519897ff446e0dc056e12402e6785cd5 + sha256: 68ac5a6a467b9c0a98e326ec4cc8e3c01d4514f1200c1b44102923424e8ed1eb + category: main + optional: false +- name: python-utils + version: 3.8.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + typing_extensions: '>3.10.0.2' + url: https://conda.anaconda.org/conda-forge/noarch/python-utils-3.8.1-pyhd8ed1ab_0.conda + hash: + md5: 4dc77041fea14c63ecea50ce0eb92873 + sha256: 769c3284ea7ffb2e6c68827429c50bd04b21b81e001353b0c72b04b43c215fc4 + category: main + optional: false +- name: python-utils + version: 3.8.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + typing_extensions: '>3.10.0.2' + url: https://conda.anaconda.org/conda-forge/noarch/python-utils-3.8.1-pyhd8ed1ab_0.conda + hash: + md5: 4dc77041fea14c63ecea50ce0eb92873 + sha256: 769c3284ea7ffb2e6c68827429c50bd04b21b81e001353b0c72b04b43c215fc4 + category: main + optional: false +- name: python-xxhash + version: 3.4.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + xxhash: '>=0.8.2,<0.8.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/python-xxhash-3.4.1-py39hd1e30aa_0.conda + hash: + md5: 756cb152772a225587a05ca0ec68fc08 + sha256: 1172021966a2227236dcab73e4f456d03d4c5afe2bbfcc25ccf7357b49539a15 + category: main + optional: false +- name: python-xxhash + version: 3.4.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + xxhash: '>=0.8.2,<0.8.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/python-xxhash-3.4.1-py39h0f82c59_0.conda + hash: + md5: e20092f69affd4e84cbbe6c048283eed + sha256: 57ffc11d26e2f981a1e35adcba4d47c8e3172a5f7d9591fbebd753924b85f9dd + category: main + optional: false +- name: python_abi + version: '3.9' + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.9-4_cp39.conda + hash: + md5: bfe4b3259a8ac6cdf0037752904da6a7 + sha256: 7e0157e35929711e1a986c18a8bfb7a38a2209cfada16b541ebb0481f74376d6 + category: main + optional: false +- name: python_abi + version: '3.9' + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/python_abi-3.9-4_cp39.conda + hash: + md5: be9e11a37bbab9cfdbcb36e52d8d73cb + sha256: 2ae06dcd1a03f023b6accf5bd989f42b689f708d3495affa22c2ed9f1d127726 + category: main + optional: false +- name: pytimeparse + version: 1.1.8 + manager: conda + platform: linux-64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/pytimeparse-1.1.8-py_0.tar.bz2 + hash: + md5: edde7e7260599f9860002187486b3e01 + sha256: 313cbde8ded706790d4fb8ea114ba1d706ff5be0780f63c01de81f569e593a03 + category: main + optional: false +- name: pytimeparse + version: 1.1.8 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/pytimeparse-1.1.8-py_0.tar.bz2 + hash: + md5: edde7e7260599f9860002187486b3e01 + sha256: 313cbde8ded706790d4fb8ea114ba1d706ff5be0780f63c01de81f569e593a03 + category: main + optional: false +- name: pytorch + version: 2.0.0 + manager: conda + platform: linux-64 + dependencies: + __glibc: '>=2.17,<3.0.a0' + _openmp_mutex: '>=4.5' + filelock: '' + jinja2: '' + libcblas: '>=3.9.0,<4.0a0' + libgcc-ng: '>=12' + libprotobuf: '>=3.21.12,<3.22.0a0' + libstdcxx-ng: '>=12' + libuv: '>=1.44.2,<2.0a0' + mkl: '>=2022.2.1,<2023.0a0' + networkx: '' + numpy: '>=1.21.6,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + sleef: '>=3.5.1,<4.0a0' + sympy: '' + typing_extensions: '' + url: https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.0.0-cpu_mkl_py39h9f63279_101.conda + hash: + md5: 75e2cdb9b19d38367cad1c14b66fc3f5 + sha256: b775669b515de43cf2de62fd3ab35a1a4e77f34cef932debcb8a3769718b8229 + category: main + optional: false +- name: pytorch + version: 2.0.0 + manager: conda + platform: osx-arm64 + dependencies: + filelock: '' + jinja2: '' + libcblas: '>=3.9.0,<4.0a0' + libcxx: '>=15.0.7' + liblapack: '>=3.9.0,<4.0a0' + libprotobuf: '>=3.21.12,<3.22.0a0' + libuv: '>=1.44.2,<2.0a0' + llvm-openmp: '>=15.0.7' + networkx: '' + nomkl: '' + numpy: '>=1.21.6,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + sleef: '>=3.5.1,<4.0a0' + sympy: '' + typing_extensions: '' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.0.0-cpu_generic_py39hb35d202_1.conda + hash: + md5: 03e438278d6510f7b56d89a39d20f0ff + sha256: 6305cf96428d35275b7ea20cd8f9e9ece4b2f4f4d029e244cfd1b8a837d8f661 + category: main + optional: false +- name: pytz + version: 2023.3.post1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/pytz-2023.3.post1-pyhd8ed1ab_0.conda + hash: + md5: c93346b446cd08c169d843ae5fc0da97 + sha256: 6b680e63d69aaf087cd43ca765a23838723ef59b0a328799e6363eb13f52c49e + category: main + optional: false +- name: pytz + version: 2023.3.post1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/pytz-2023.3.post1-pyhd8ed1ab_0.conda + hash: + md5: c93346b446cd08c169d843ae5fc0da97 + sha256: 6b680e63d69aaf087cd43ca765a23838723ef59b0a328799e6363eb13f52c49e + category: main + optional: false +- name: pyu2f + version: 0.1.5 + manager: conda + platform: linux-64 + dependencies: + python: '>=2.7' + six: '' + url: https://conda.anaconda.org/conda-forge/noarch/pyu2f-0.1.5-pyhd8ed1ab_0.tar.bz2 + hash: + md5: caabbeaa83928d0c3e3949261daa18eb + sha256: 667a5a30b65a60b15f38fa4cb09efd6d2762b5a0a9563acd9555eaa5e0b953a2 + category: main + optional: false +- name: pyu2f + version: 0.1.5 + manager: conda + platform: osx-arm64 + dependencies: + six: '' + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/pyu2f-0.1.5-pyhd8ed1ab_0.tar.bz2 + hash: + md5: caabbeaa83928d0c3e3949261daa18eb + sha256: 667a5a30b65a60b15f38fa4cb09efd6d2762b5a0a9563acd9555eaa5e0b953a2 + category: main + optional: false +- name: pywin32-on-windows + version: 0.1.0 + manager: conda + platform: linux-64 + dependencies: + __unix: '' + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + hash: + md5: 2807a0becd1d986fe1ef9b7f8135f215 + sha256: 6502696aaef571913b22a808b15c185bd8ea4aabb952685deb29e6a6765761cb + category: main + optional: false +- name: pywin32-on-windows + version: 0.1.0 + manager: conda + platform: osx-arm64 + dependencies: + __unix: '' + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + hash: + md5: 2807a0becd1d986fe1ef9b7f8135f215 + sha256: 6502696aaef571913b22a808b15c185bd8ea4aabb952685deb29e6a6765761cb + category: main + optional: false +- name: pyyaml + version: 6.0.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + yaml: '>=0.2.5,<0.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py39hd1e30aa_1.conda + hash: + md5: 37218233bcdc310e4fde6453bc1b40d8 + sha256: 28b147c50ad48215f9427a52811848223ac0371be7caae88522e661a3bfb1448 + category: main + optional: false +- name: pyyaml + version: 6.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + yaml: '>=0.2.5,<0.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.1-py39h0f82c59_1.conda + hash: + md5: b4f3bbf710410751f687ac04544c12b1 + sha256: 96ef332c1199bed9779f6b5bf7671dd00654208a6fadb7b89d744e66286326dc + category: main + optional: false +- name: pyzmq + version: 25.1.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libsodium: '>=1.0.18,<1.0.19.0a0' + libstdcxx-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + zeromq: '>=4.3.5,<4.4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-25.1.2-py39h8c080ef_0.conda + hash: + md5: 852eb7bf636d4108530a27100c23f1c1 + sha256: ada6b641a9fca2a4a7efe72bb5133d3da89bc52ac16a1d67083c065bdccdb321 + category: main + optional: false +- name: pyzmq + version: 25.1.2 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + libcxx: '>=16.0.6' + libsodium: '>=1.0.18,<1.0.19.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + zeromq: '>=4.3.5,<4.4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-25.1.2-py39he1e2164_0.conda + hash: + md5: d4011b876d36c431553f6db2b3c7bad9 + sha256: 23e9a498414af4613c51d93dd74c6c20f63a03545c7b11b7b0bdeaf70f194d1c + category: main + optional: false +- name: qtconsole-base + version: 5.5.1 + manager: conda + platform: linux-64 + dependencies: + ipykernel: '>=4.1' + jupyter_client: '>=4.1' + jupyter_core: '' + packaging: '' + pygments: '' + python: '>=3.8' + qtpy: '>=2.4.0' + traitlets: '' + url: https://conda.anaconda.org/conda-forge/noarch/qtconsole-base-5.5.1-pyha770c72_0.conda + hash: + md5: 5528a3eda283b421055c89bface19a1c + sha256: e81a294941a598aabfd9462cf9aaa3b3e2c04996420f82494bdc13233de8ca70 + category: main + optional: false +- name: qtconsole-base + version: 5.5.1 + manager: conda + platform: osx-arm64 + dependencies: + packaging: '' + pygments: '' + traitlets: '' + jupyter_core: '' + python: '>=3.8' + ipykernel: '>=4.1' + jupyter_client: '>=4.1' + qtpy: '>=2.4.0' + url: https://conda.anaconda.org/conda-forge/noarch/qtconsole-base-5.5.1-pyha770c72_0.conda + hash: + md5: 5528a3eda283b421055c89bface19a1c + sha256: e81a294941a598aabfd9462cf9aaa3b3e2c04996420f82494bdc13233de8ca70 + category: main + optional: false +- name: qtpy + version: 2.4.1 + manager: conda + platform: linux-64 + dependencies: + packaging: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/qtpy-2.4.1-pyhd8ed1ab_0.conda + hash: + md5: 7f391bd70d2abfb70f304ba5aa4e1261 + sha256: 925bf48e747af6ceff1b073c10b12fc94ef79c88a34729059d253e43466a33f1 + category: main + optional: false +- name: qtpy + version: 2.4.1 + manager: conda + platform: osx-arm64 + dependencies: + packaging: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/qtpy-2.4.1-pyhd8ed1ab_0.conda + hash: + md5: 7f391bd70d2abfb70f304ba5aa4e1261 + sha256: 925bf48e747af6ceff1b073c10b12fc94ef79c88a34729059d253e43466a33f1 + category: main + optional: false +- name: querystring_parser + version: 1.2.4 + manager: conda + platform: linux-64 + dependencies: + python: '' + requests: '' + six: '' + url: https://conda.anaconda.org/conda-forge/noarch/querystring_parser-1.2.4-py_0.tar.bz2 + hash: + md5: 0ebdca9b753c2e082e5b5ad06aa76b41 + sha256: 06977a9af6d8605fb6068d8af6bb9c1cb565f8f5e15aa6cf0fb94109d4148b54 + category: main + optional: false +- name: querystring_parser + version: 1.2.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + requests: '' + six: '' + url: https://conda.anaconda.org/conda-forge/noarch/querystring_parser-1.2.4-py_0.tar.bz2 + hash: + md5: 0ebdca9b753c2e082e5b5ad06aa76b41 + sha256: 06977a9af6d8605fb6068d8af6bb9c1cb565f8f5e15aa6cf0fb94109d4148b54 + category: main + optional: false +- name: rdma-core + version: '28.9' + manager: conda + platform: linux-64 + dependencies: + __glibc: '>=2.17,<3.0.a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/rdma-core-28.9-h59595ed_1.conda + hash: + md5: aeffb7c06b5f65e55e6c637408dc4100 + sha256: 832f9393ab3144ce6468c6f150db9d398fad4451e96a8879afb3059f0c9902f6 + category: main + optional: false +- name: re2 + version: 2023.03.02 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/re2-2023.03.02-h8c504da_0.conda + hash: + md5: 206f8fa808748f6e90599c3368a1114e + sha256: 1727f893a352ca735fb96b09f9edf6fe18c409d65550fd37e8a192919e8c827b + category: main + optional: false +- name: re2 + version: 2023.03.02 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=14.0.6' + url: https://conda.anaconda.org/conda-forge/osx-arm64/re2-2023.03.02-hc5e2d97_0.conda + hash: + md5: 7a851c0ab05247e3246eca2c3b243b9a + sha256: 39bc32dcef3b699e6f748cc51d5e6b05ab788334d5787c64f069f0122e74c0c5 + category: main + optional: false +- name: readline + version: '8.2' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + ncurses: '>=6.3,<7.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda + hash: + md5: 47d31b792659ce70f470b5c82fdfb7a4 + sha256: 5435cf39d039387fbdc977b0a762357ea909a7694d9528ab40f005e9208744d7 + category: main + optional: false +- name: readline + version: '8.2' + manager: conda + platform: osx-arm64 + dependencies: + ncurses: '>=6.3,<7.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda + hash: + md5: 8cbb776a2f641b943d413b3e19df71f4 + sha256: a1dfa679ac3f6007362386576a704ad2d0d7a02e98f5d0b115f207a2da63e884 + category: main + optional: false +- name: recommonmark + version: 0.7.1 + manager: conda + platform: linux-64 + dependencies: + commonmark: '>=0.8.1' + docutils: '>=0.11' + python: '>=3' + sphinx: '>=1.3.1' + url: https://conda.anaconda.org/conda-forge/noarch/recommonmark-0.7.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: b3becf9905b8c7ba839072f65e693253 + sha256: 2bd6134e7540a1d458be34aef4a94a839540cba29ac75cc558be6a394549b8a6 + category: main + optional: false +- name: recommonmark + version: 0.7.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3' + docutils: '>=0.11' + commonmark: '>=0.8.1' + sphinx: '>=1.3.1' + url: https://conda.anaconda.org/conda-forge/noarch/recommonmark-0.7.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: b3becf9905b8c7ba839072f65e693253 + sha256: 2bd6134e7540a1d458be34aef4a94a839540cba29ac75cc558be6a394549b8a6 + category: main + optional: false +- name: referencing + version: 0.32.0 + manager: conda + platform: linux-64 + dependencies: + attrs: '>=22.2.0' + python: '>=3.8' + rpds-py: '>=0.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/referencing-0.32.0-pyhd8ed1ab_0.conda + hash: + md5: a7b5a535cd614e384594530aee7e6061 + sha256: dfd40282910a45e58882ed94b502b2a09f475efb04eaaa3bd8b3b5a9b21a19c3 + category: main + optional: false +- name: referencing + version: 0.32.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + attrs: '>=22.2.0' + rpds-py: '>=0.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/referencing-0.32.0-pyhd8ed1ab_0.conda + hash: + md5: a7b5a535cd614e384594530aee7e6061 + sha256: dfd40282910a45e58882ed94b502b2a09f475efb04eaaa3bd8b3b5a9b21a19c3 + category: main + optional: false +- name: requests + version: 2.31.0 + manager: conda + platform: linux-64 + dependencies: + certifi: '>=2017.4.17' + charset-normalizer: '>=2,<4' + idna: '>=2.5,<4' + python: '>=3.7' + urllib3: '>=1.21.1,<3' + url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + hash: + md5: a30144e4156cdbb236f99ebb49828f8b + sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad + category: main + optional: false +- name: requests + version: 2.31.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + idna: '>=2.5,<4' + certifi: '>=2017.4.17' + charset-normalizer: '>=2,<4' + urllib3: '>=1.21.1,<3' + url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + hash: + md5: a30144e4156cdbb236f99ebb49828f8b + sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad + category: main + optional: false +- name: requests-oauthlib + version: 1.3.1 + manager: conda + platform: linux-64 + dependencies: + oauthlib: '>=3.0.0' + python: '>=3.4' + requests: '>=2.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/requests-oauthlib-1.3.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 61b279f051eef9c89d58f4d813e75e04 + sha256: 889e3c1b84467b64046776db95dc4c5ea4dad5afaa5ec18ad811bd95c63286b0 + category: main + optional: false +- name: requests-oauthlib + version: 1.3.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.4' + requests: '>=2.0.0' + oauthlib: '>=3.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/requests-oauthlib-1.3.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 61b279f051eef9c89d58f4d813e75e04 + sha256: 889e3c1b84467b64046776db95dc4c5ea4dad5afaa5ec18ad811bd95c63286b0 + category: main + optional: false +- name: retry + version: 0.9.2 + manager: conda + platform: linux-64 + dependencies: + decorator: '>=3.4.2' + py: '>=1.4.26,<2.0.0' + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/retry-0.9.2-py_0.tar.bz2 + hash: + md5: b83b7289405e8aab02d1a72bc14506f8 + sha256: 9066f5507fb8d143a01fe1462bf416680edbd3e1dd0efc9ce4124cd8b74acb15 + category: main + optional: false +- name: retry + version: 0.9.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + decorator: '>=3.4.2' + py: '>=1.4.26,<2.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/retry-0.9.2-py_0.tar.bz2 + hash: + md5: b83b7289405e8aab02d1a72bc14506f8 + sha256: 9066f5507fb8d143a01fe1462bf416680edbd3e1dd0efc9ce4124cd8b74acb15 + category: main + optional: false +- name: rfc3339-validator + version: 0.1.4 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + six: '' + url: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 + hash: + md5: fed45fc5ea0813240707998abe49f520 + sha256: 7c7052b51de0b5c558f890bb11f8b5edbb9934a653d76be086b1182b9f54185d + category: main + optional: false +- name: rfc3339-validator + version: 0.1.4 + manager: conda + platform: osx-arm64 + dependencies: + six: '' + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 + hash: + md5: fed45fc5ea0813240707998abe49f520 + sha256: 7c7052b51de0b5c558f890bb11f8b5edbb9934a653d76be086b1182b9f54185d + category: main + optional: false +- name: rfc3986-validator + version: 0.1.1 + manager: conda + platform: linux-64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + hash: + md5: 912a71cc01012ee38e6b90ddd561e36f + sha256: 2a5b495a1de0f60f24d8a74578ebc23b24aa53279b1ad583755f223097c41c37 + category: main + optional: false +- name: rfc3986-validator + version: 0.1.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + hash: + md5: 912a71cc01012ee38e6b90ddd561e36f + sha256: 2a5b495a1de0f60f24d8a74578ebc23b24aa53279b1ad583755f223097c41c37 + category: main + optional: false +- name: rich + version: 13.7.0 + manager: conda + platform: linux-64 + dependencies: + markdown-it-py: '>=2.2.0' + pygments: '>=2.13.0,<3.0.0' + python: '>=3.7.0' + typing_extensions: '>=4.0.0,<5.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.0-pyhd8ed1ab_0.conda + hash: + md5: d7a11d4f3024b2f4a6e0ae7377dd61e9 + sha256: 4bb25bf1f5664772b2c4c2e3878aa6e7dc2695f97e3da4ee8e47c51e179913bb + category: main + optional: false +- name: rich + version: 13.7.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7.0' + typing_extensions: '>=4.0.0,<5.0.0' + pygments: '>=2.13.0,<3.0.0' + markdown-it-py: '>=2.2.0' + url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.0-pyhd8ed1ab_0.conda + hash: + md5: d7a11d4f3024b2f4a6e0ae7377dd61e9 + sha256: 4bb25bf1f5664772b2c4c2e3878aa6e7dc2695f97e3da4ee8e47c51e179913bb + category: main + optional: false +- name: rich-click + version: 1.7.2 + manager: conda + platform: linux-64 + dependencies: + click: '>=7,<9' + python: '>=3.7' + rich: '>=10' + url: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.7.2-pyhd8ed1ab_0.conda + hash: + md5: fe1eae76a71246959cefd09b5b00869b + sha256: 4bfddbc5716a09bfea1c3345b1eed0ddb36d0e55f357afb60ca3e73c9231cc68 + category: main + optional: false +- name: rich-click + version: 1.7.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + click: '>=7,<9' + rich: '>=10' + url: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.7.2-pyhd8ed1ab_0.conda + hash: + md5: fe1eae76a71246959cefd09b5b00869b + sha256: 4bfddbc5716a09bfea1c3345b1eed0ddb36d0e55f357afb60ca3e73c9231cc68 + category: main + optional: false +- name: rpds-py + version: 0.13.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.13.2-py39h9fdd4d6_0.conda + hash: + md5: 75f11bc5ee4f3cf1d12bc17066b6a367 + sha256: f7e4dc74a7c8928edd8bf63316f09443943faf723487310c0f4ab76a5c62a5e6 + category: main + optional: false +- name: rpds-py + version: 0.13.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.13.2-py39h8fec3ad_0.conda + hash: + md5: b728c70cc4b7e617535a3e92769608a9 + sha256: fdfada05bed7be977e070ce0e4b4f1d478b5c4c71ee04508529cd34a8cc072dd + category: main + optional: false +- name: rsa + version: '4.9' + manager: conda + platform: linux-64 + dependencies: + pyasn1: '>=0.1.3' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/rsa-4.9-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 03bf410858b2cefc267316408a77c436 + sha256: 23214cdc15a41d14136754857fd9cd46ca3c55a7e751da3b3a48c673f0ee2a57 + category: main + optional: false +- name: rsa + version: '4.9' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + pyasn1: '>=0.1.3' + url: https://conda.anaconda.org/conda-forge/noarch/rsa-4.9-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 03bf410858b2cefc267316408a77c436 + sha256: 23214cdc15a41d14136754857fd9cd46ca3c55a7e751da3b3a48c673f0ee2a57 + category: main + optional: false +- name: rtree + version: 1.1.0 + manager: conda + platform: linux-64 + dependencies: + libspatialindex: '>=1.9.3,<1.9.4.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.1.0-py39hb102c33_0.conda + hash: + md5: 1734349023b5f589f4a58201fec76ae3 + sha256: 4efb16fae3f439bea1c1fb3f5557a3a0e789c1df9fc403686678a0b191a7be1d + category: main + optional: false +- name: ruamel.yaml + version: 0.17.17 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + ruamel.yaml.clib: '>=0.1.2' + setuptools: '' + url: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.17.17-py39hd1e30aa_2.conda + hash: + md5: f4795f900e05e8bcedbad86ec8a1b678 + sha256: eb70d985ce60baa5a8ba1a5b0ab49dcf2173f326ae3d77faadf38174253e9b66 + category: main + optional: false +- name: ruamel.yaml + version: 0.17.17 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + ruamel.yaml.clib: '>=0.1.2' + setuptools: '' + url: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml-0.17.17-py39h17cfd9d_2.conda + hash: + md5: 2cd2b293f4a2b7b34575aecf8946b21d + sha256: 3cb0dbbc0725805f62cbbc7614933c9e69a8d530cb21ffa8209a1caf6a1b8c1a + category: main + optional: false +- name: ruamel.yaml.clib + version: 0.2.7 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.7-py39hd1e30aa_2.conda + hash: + md5: 743d996a1af8502f27770fadfd418434 + sha256: 06b089d59ffebef9c9171a8a3480adcb6e7f112caef9f8b87591207427cb1cf1 + category: main + optional: false +- name: ruamel.yaml.clib + version: 0.2.7 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml.clib-0.2.7-py39h0f82c59_2.conda + hash: + md5: f3e2f7730c751b6ce8cf7995d1f47ebd + sha256: 3cd6dbe76582646d1366f20e0f02dde700969dbedf65f6f1434ce76ba1ec924e + category: main + optional: false +- name: s2n + version: 1.3.49 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + openssl: '>=3.1.2,<4.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.3.49-h06160fa_0.conda + hash: + md5: 1d78349eb26366ecc034a4afe70a8534 + sha256: 7ef7af04a626003737ad311fe45165addcb53928117f1a892b78114f74be724c + category: main + optional: false +- name: s3fs + version: 0.6.0 + manager: conda + platform: linux-64 + dependencies: + aiobotocore: '' + botocore: '' + fsspec: '>=0.9.0' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/s3fs-0.6.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: f20c8f33a3aa1256d88dd4b5bc67530c + sha256: 36d2b377c87acb3f5958e00d6ef5acd36f89a903fc54ba98084a2fccb7e2e051 + category: main + optional: false +- name: s3fs + version: 0.6.0 + manager: conda + platform: osx-arm64 + dependencies: + botocore: '' + aiobotocore: '' + python: '>=3.6' + fsspec: '>=0.9.0' + url: https://conda.anaconda.org/conda-forge/noarch/s3fs-0.6.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: f20c8f33a3aa1256d88dd4b5bc67530c + sha256: 36d2b377c87acb3f5958e00d6ef5acd36f89a903fc54ba98084a2fccb7e2e051 + category: main + optional: false +- name: scikit-learn + version: 1.3.2 + manager: conda + platform: linux-64 + dependencies: + _openmp_mutex: '>=4.5' + joblib: '>=1.1.1' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + numpy: '>=1.22.4,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + scipy: '' + threadpoolctl: '>=2.0.0' + url: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.3.2-py39ha22ef79_2.conda + hash: + md5: bdd0cdcd58ced4168aeef7046663f2f6 + sha256: 32e66143b566e558f414e461f99011e8ccddbfc87c4bb3de77f86450f807f54c + category: main + optional: false +- name: scikit-learn + version: 1.3.2 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + joblib: '>=1.1.1' + libcxx: '>=16.0.6' + llvm-openmp: '>=17.0.6' + numpy: '>=1.22.4,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + scipy: '' + threadpoolctl: '>=2.0.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.3.2-py39h172c841_2.conda + hash: + md5: 3f6ead0da40ab93f9d20b624bc3b1c87 + sha256: 4b81346f420e09990dd799acf89376a27d383927663c2dab968c59aa9a6f4212 + category: main + optional: false +- name: scipy + version: 1.11.4 + manager: conda + platform: linux-64 + dependencies: + libblas: '>=3.9.0,<4.0a0' + libcblas: '>=3.9.0,<4.0a0' + libgcc-ng: '>=12' + libgfortran-ng: '' + libgfortran5: '>=12.3.0' + liblapack: '>=3.9.0,<4.0a0' + libstdcxx-ng: '>=12' + numpy: '>=1.22.4,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.11.4-py39h474f0d3_0.conda + hash: + md5: 4b401c1516417b4b14aa1249d2f7929d + sha256: c3f0c06d2285b249a26a050e0464957eeb7e6b1fac93e3acd4218123fd1047db + category: main + optional: false +- name: scipy + version: 1.11.4 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + libblas: '>=3.9.0,<4.0a0' + libcblas: '>=3.9.0,<4.0a0' + libcxx: '>=16.0.6' + libgfortran: 5.* + libgfortran5: '>=13.2.0' + liblapack: '>=3.9.0,<4.0a0' + numpy: '>=1.22.4,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.11.4-py39h36c428d_0.conda + hash: + md5: 5a7b8c8fdec2c065b32dbd0e1b3b41ee + sha256: 960a1a8225fdd52442cd3740f8bd40057caee527ba49de2991760843afe71bba + category: main + optional: false +- name: secretstorage + version: 3.3.3 + manager: conda + platform: linux-64 + dependencies: + cryptography: '' + dbus: '' + jeepney: '>=0.6' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/secretstorage-3.3.3-py39hf3d152e_2.conda + hash: + md5: 0e6f3ef2dd562ed33d2a18d9c6f78d88 + sha256: efff009fd24eca4cf1ecdb5010d605db11078f08be7d046d8d23a2e0e63e5015 + category: main + optional: false +- name: send2trash + version: 1.8.2 + manager: conda + platform: linux-64 + dependencies: + __linux: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.2-pyh41d4057_0.conda + hash: + md5: ada5a17adcd10be4fc7e37e4166ba0e2 + sha256: e74d3faf51a6cc429898da0209d95b209270160f3edbf2f6d8b61a99428301cd + category: main + optional: false +- name: send2trash + version: 1.8.2 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '' + pyobjc-framework-cocoa: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.2-pyhd1c38e8_0.conda + hash: + md5: 2657c3de5371c571aef6678afb4aaadd + sha256: dca4022bae47618ed738ab7d45ead5202d174b741cfb98e4484acdc6e76da32a + category: main + optional: false +- name: setuptools + version: 68.2.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-68.2.2-pyhd8ed1ab_0.conda + hash: + md5: fc2166155db840c634a1291a5c35a709 + sha256: 851901b1f8f2049edb36a675f0c3f9a98e1495ef4eb214761b048c6f696a06f7 + category: main + optional: false +- name: setuptools + version: 59.8.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/setuptools-59.8.0-py39h2804cbe_1.tar.bz2 + hash: + md5: 27c3effc9a6ae935378b603157461239 + sha256: 7c02e55039e0514184cb4debd2fadedf5223bf0ac9a5eae2ff49bf6e1e314285 + category: main + optional: false +- name: shapely + version: 2.0.2 + manager: conda + platform: linux-64 + dependencies: + geos: '>=3.12.1,<3.12.2.0a0' + libgcc-ng: '>=12' + numpy: '>=1.22.4,<2.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/shapely-2.0.2-py39h6404dd3_1.conda + hash: + md5: 05623249055d99c51cde021b525611db + sha256: 3225b43b4be766d2bb1335b7942a76731f3bb69485f8bc49a76699e73336cc73 + category: main + optional: false +- name: six + version: 1.16.0 + manager: conda + platform: linux-64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2 + hash: + md5: e5f25f8dbc060e9a8d912e432202afc2 + sha256: a85c38227b446f42c5b90d9b642f2c0567880c15d72492d8da074a59c8f91dd6 + category: main + optional: false +- name: six + version: 1.16.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2 + hash: + md5: e5f25f8dbc060e9a8d912e432202afc2 + sha256: a85c38227b446f42c5b90d9b642f2c0567880c15d72492d8da074a59c8f91dd6 + category: main + optional: false +- name: skl2onnx + version: 1.15.0 + manager: conda + platform: linux-64 + dependencies: + numpy: '>=1.15' + onnx: '>=1.2.1' + onnxconverter-common: '>=1.7.0' + packaging: '' + protobuf: '' + python: '>=3.6' + scikit-learn: '>=0.19' + scipy: '>=1.0' + url: https://conda.anaconda.org/conda-forge/noarch/skl2onnx-1.15.0-pyhd8ed1ab_0.conda + hash: + md5: 419daff5a7f0272b5e36a048654945cd + sha256: 1b5358556fea44d9397bb9dca29a6e5e62f67794b0411317371d6a9ab1f6b660 + category: main + optional: false +- name: skl2onnx + version: 1.15.0 + manager: conda + platform: osx-arm64 + dependencies: + packaging: '' + protobuf: '' + python: '>=3.6' + numpy: '>=1.15' + scipy: '>=1.0' + scikit-learn: '>=0.19' + onnxconverter-common: '>=1.7.0' + onnx: '>=1.2.1' + url: https://conda.anaconda.org/conda-forge/noarch/skl2onnx-1.15.0-pyhd8ed1ab_0.conda + hash: + md5: 419daff5a7f0272b5e36a048654945cd + sha256: 1b5358556fea44d9397bb9dca29a6e5e62f67794b0411317371d6a9ab1f6b660 + category: main + optional: false +- name: sleef + version: 3.5.1 + manager: conda + platform: linux-64 + dependencies: + _openmp_mutex: '>=4.5' + libgcc-ng: '>=9.4.0' + url: https://conda.anaconda.org/conda-forge/linux-64/sleef-3.5.1-h9b69904_2.tar.bz2 + hash: + md5: 6e016cf4c525d04a7bd038cee53ad3fd + sha256: 77d644a16f682e6d01df63fe9d25315011393498b63cf08c0e548780e46b2170 + category: main + optional: false +- name: sleef + version: 3.5.1 + manager: conda + platform: osx-arm64 + dependencies: + llvm-openmp: '>=12.0.1' + url: https://conda.anaconda.org/conda-forge/osx-arm64/sleef-3.5.1-h156473d_2.tar.bz2 + hash: + md5: bd159e7f04dbf79b06ed2bd37e112458 + sha256: a3d20bed697aaababfcb53ca2011486cf5e44e20855142c170fa0826df5f952c + category: main + optional: false +- name: smmap + version: 5.0.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/smmap-5.0.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 62f26a3d1387acee31322208f0cfa3e0 + sha256: 23011cb3e064525bdb8787c75126a2e78d2344a72cd6773922006d1da1f2af16 + category: main + optional: false +- name: smmap + version: 5.0.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/smmap-5.0.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 62f26a3d1387acee31322208f0cfa3e0 + sha256: 23011cb3e064525bdb8787c75126a2e78d2344a72cd6773922006d1da1f2af16 + category: main + optional: false +- name: snappy + version: 1.1.10 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.1.10-h9fff704_0.conda + hash: + md5: e6d228cd0bb74a51dd18f5bfce0b4115 + sha256: 02219f2382b4fe39250627dade087a4412d811936a5a445636b7260477164eac + category: main + optional: false +- name: snappy + version: 1.1.10 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=14.0.6' + url: https://conda.anaconda.org/conda-forge/osx-arm64/snappy-1.1.10-h17c5cce_0.conda + hash: + md5: ac82a611d1a67a598096ebaa857198e3 + sha256: dfae03cd2339587871e53b42833657faa4c9e42e3e2c56ee9e32bc60797c7f62 + category: main + optional: false +- name: sniffio + version: 1.3.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: dd6cbc539e74cb1f430efbd4575b9303 + sha256: a3fd30754c20ddb28b777db38345ea00d958f46701f0decd6291a81c0f4eee78 + category: main + optional: false +- name: sniffio + version: 1.3.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: dd6cbc539e74cb1f430efbd4575b9303 + sha256: a3fd30754c20ddb28b777db38345ea00d958f46701f0decd6291a81c0f4eee78 + category: main + optional: false +- name: snowballstemmer + version: 2.2.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=2' + url: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 4d22a9315e78c6827f806065957d566e + sha256: a0fd916633252d99efb6223b1050202841fa8d2d53dacca564b0ed77249d3228 + category: main + optional: false +- name: snowballstemmer + version: 2.2.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=2' + url: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 4d22a9315e78c6827f806065957d566e + sha256: a0fd916633252d99efb6223b1050202841fa8d2d53dacca564b0ed77249d3228 + category: main + optional: false +- name: snowflake-connector-python + version: 3.5.0 + manager: conda + platform: linux-64 + dependencies: + asn1crypto: '>0.24.0,<2.0.0' + certifi: '>=2017.4.17' + cffi: '>=1.9,<2.0.0' + charset-normalizer: '>=2,<4' + cryptography: '>=3.1.0,<42.0.0' + filelock: '>=3.5,<4' + idna: '>=2.5,<4' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + numpy: '>=1.22.4,<2.0a0' + packaging: '' + platformdirs: '>=2.6.0,<3.9.0' + pyjwt: <3.0.0 + pyopenssl: '>=16.2.0,<24.0.0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + pytz: '' + requests: <3.0.0 + sortedcontainers: '>=2.4.0' + tomlkit: '' + typing_extensions: '>=4.3,<5' + urllib3: '>=1.21.1,<2' + url: https://conda.anaconda.org/conda-forge/linux-64/snowflake-connector-python-3.5.0-py39hddac248_1.conda + hash: + md5: 60e2cbfb8a0be04b34abb3d6d54e87fc + sha256: f1bf2a9a7fc9860a0f5569441c3bf94094003859c52af331202a1624857a7a2f + category: main + optional: false +- name: snowflake-connector-python + version: 3.5.0 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + asn1crypto: '>0.24.0,<2.0.0' + certifi: '>=2017.4.17' + cffi: '>=1.9,<2.0.0' + charset-normalizer: '>=2,<4' + cryptography: '>=3.1.0,<42.0.0' + filelock: '>=3.5,<4' + idna: '>=2.5,<4' + libcxx: '>=16.0.6' + numpy: '>=1.22.4,<2.0a0' + packaging: '' + platformdirs: '>=2.6.0,<3.9.0' + pyjwt: <3.0.0 + pyopenssl: '>=16.2.0,<24.0.0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + pytz: '' + requests: <3.0.0 + sortedcontainers: '>=2.4.0' + tomlkit: '' + typing_extensions: '>=4.3,<5' + urllib3: '>=1.21.1,<2' + url: https://conda.anaconda.org/conda-forge/osx-arm64/snowflake-connector-python-3.5.0-py39hf8cecc8_1.conda + hash: + md5: b6f41545acdb216a81077dba2c35cab1 + sha256: 8f57754fcad7530da7f3ee17b96c4ba3191f9fc95d45bf580ad3d02eeb6c7083 + category: main + optional: false +- name: sortedcontainers + version: 2.4.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 6d6552722448103793743dabfbda532d + sha256: 0cea408397d50c2afb2d25e987ebac4546ae11e549d65b1403d80dc368dfaaa6 + category: main + optional: false +- name: sortedcontainers + version: 2.4.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 6d6552722448103793743dabfbda532d + sha256: 0cea408397d50c2afb2d25e987ebac4546ae11e549d65b1403d80dc368dfaaa6 + category: main + optional: false +- name: soupsieve + version: '2.5' + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda + hash: + md5: 3f144b2c34f8cb5a9abd9ed23a39c561 + sha256: 54ae221033db8fbcd4998ccb07f3c3828b4d77e73b0c72b18c1d6a507059059c + category: main + optional: false +- name: soupsieve + version: '2.5' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda + hash: + md5: 3f144b2c34f8cb5a9abd9ed23a39c561 + sha256: 54ae221033db8fbcd4998ccb07f3c3828b4d77e73b0c72b18c1d6a507059059c + category: main + optional: false +- name: sphinx + version: 4.5.0 + manager: conda + platform: linux-64 + dependencies: + alabaster: '>=0.7,<0.8' + babel: '>=1.3' + colorama: '>=0.3.5' + docutils: '>=0.14,<0.18' + imagesize: '' + importlib-metadata: '>=4.4' + jinja2: '>=2.3' + packaging: '' + pygments: '>=2.0' + python: '>=3.6' + requests: '>=2.5.0' + snowballstemmer: '>=1.1' + sphinxcontrib-applehelp: '' + sphinxcontrib-devhelp: '' + sphinxcontrib-htmlhelp: '>=2.0.0' + sphinxcontrib-jsmath: '' + sphinxcontrib-qthelp: '' + sphinxcontrib-serializinghtml: '>=1.1.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-4.5.0-pyh6c4a22f_0.tar.bz2 + hash: + md5: 46b38d88c4270ff9ba78a89c83c66345 + sha256: 2fe70d936cc969e20f07a7df64438587261f187d4f08e1c0f412cdd1d632730c + category: main + optional: false +- name: sphinx + version: 4.5.0 + manager: conda + platform: osx-arm64 + dependencies: + packaging: '' + sphinxcontrib-jsmath: '' + sphinxcontrib-applehelp: '' + sphinxcontrib-devhelp: '' + sphinxcontrib-qthelp: '' + imagesize: '' + python: '>=3.6' + pygments: '>=2.0' + alabaster: '>=0.7,<0.8' + importlib-metadata: '>=4.4' + requests: '>=2.5.0' + jinja2: '>=2.3' + snowballstemmer: '>=1.1' + babel: '>=1.3' + sphinxcontrib-htmlhelp: '>=2.0.0' + sphinxcontrib-serializinghtml: '>=1.1.5' + colorama: '>=0.3.5' + docutils: '>=0.14,<0.18' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-4.5.0-pyh6c4a22f_0.tar.bz2 + hash: + md5: 46b38d88c4270ff9ba78a89c83c66345 + sha256: 2fe70d936cc969e20f07a7df64438587261f187d4f08e1c0f412cdd1d632730c + category: main + optional: false +- name: sphinx-autoapi + version: 2.1.0 + manager: conda + platform: linux-64 + dependencies: + astroid: '>=2.7' + jinja2: '' + python: '>=3.6' + pyyaml: '' + sphinx: '>=3.0' + sphinxcontrib-dotnetdomain: '' + sphinxcontrib-golangdomain: '' + unidecode: '' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-autoapi-2.1.0-pyhd8ed1ab_0.conda + hash: + md5: 6cb2b182390f837ce98737e92b9461f7 + sha256: 07f4a813627c3b4f4e1175366b58574d886f14ea94df855c3c69cb0676d004e4 + category: main + optional: false +- name: sphinx-autoapi + version: 2.1.0 + manager: conda + platform: osx-arm64 + dependencies: + pyyaml: '' + jinja2: '' + unidecode: '' + sphinxcontrib-dotnetdomain: '' + sphinxcontrib-golangdomain: '' + python: '>=3.6' + sphinx: '>=3.0' + astroid: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-autoapi-2.1.0-pyhd8ed1ab_0.conda + hash: + md5: 6cb2b182390f837ce98737e92b9461f7 + sha256: 07f4a813627c3b4f4e1175366b58574d886f14ea94df855c3c69cb0676d004e4 + category: main + optional: false +- name: sphinx-basic-ng + version: 1.0.0b2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + sphinx: '>=4.0,<8.0' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-basic-ng-1.0.0b2-pyhd8ed1ab_1.conda + hash: + md5: a631f5c7b7f5045448f966ad71aa2881 + sha256: 3c7a6a8bb6c9921741ef940cd61ff1694beac3c95ca7e9ad4b0ea32e2f6ac2fa + category: main + optional: false +- name: sphinx-basic-ng + version: 1.0.0b2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + sphinx: '>=4.0,<8.0' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-basic-ng-1.0.0b2-pyhd8ed1ab_1.conda + hash: + md5: a631f5c7b7f5045448f966ad71aa2881 + sha256: 3c7a6a8bb6c9921741ef940cd61ff1694beac3c95ca7e9ad4b0ea32e2f6ac2fa + category: main + optional: false +- name: sphinx-click + version: 5.1.0 + manager: conda + platform: linux-64 + dependencies: + click: '>=6.0' + python: '>=3.6' + sphinx: '>=2.0' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-click-5.1.0-pyhd8ed1ab_0.conda + hash: + md5: 3d7a8ef24d20f30ed2ce7468b8ae5c89 + sha256: 1ad63a6f1dc72cc10ee67217cdfc64f6f8c0a827a1afa0c89d0e6306762945bd + category: main + optional: false +- name: sphinx-click + version: 5.1.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + click: '>=6.0' + sphinx: '>=2.0' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-click-5.1.0-pyhd8ed1ab_0.conda + hash: + md5: 3d7a8ef24d20f30ed2ce7468b8ae5c89 + sha256: 1ad63a6f1dc72cc10ee67217cdfc64f6f8c0a827a1afa0c89d0e6306762945bd + category: main + optional: false +- name: sphinx-copybutton + version: 0.5.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3' + sphinx: '>=1.8' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_0.conda + hash: + md5: ac832cc43adc79118cf6e23f1f9b8995 + sha256: 7ea21f009792e7c69612ddba367afe0412b3fdff2e92f439e8cd222de4b40bfe + category: main + optional: false +- name: sphinx-copybutton + version: 0.5.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3' + sphinx: '>=1.8' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_0.conda + hash: + md5: ac832cc43adc79118cf6e23f1f9b8995 + sha256: 7ea21f009792e7c69612ddba367afe0412b3fdff2e92f439e8cd222de4b40bfe + category: main + optional: false +- name: sphinx-inline-tabs + version: 2023.4.21 + manager: conda + platform: linux-64 + dependencies: + beautifulsoup4: '' + python: '>=3.6' + sphinx: '>3' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-inline-tabs-2023.4.21-pyhd8ed1ab_0.conda + hash: + md5: 4addb035e43d09440597352079305513 + sha256: 142f45bb224380f13f800ae3769f0d2aa3efcd9c49e5389b48863d03c08a801a + category: main + optional: false +- name: sphinx-inline-tabs + version: 2023.4.21 + manager: conda + platform: osx-arm64 + dependencies: + beautifulsoup4: '' + python: '>=3.6' + sphinx: '>3' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-inline-tabs-2023.4.21-pyhd8ed1ab_0.conda + hash: + md5: 4addb035e43d09440597352079305513 + sha256: 142f45bb224380f13f800ae3769f0d2aa3efcd9c49e5389b48863d03c08a801a + category: main + optional: false +- name: sphinx-issues + version: 1.2.0 + manager: conda + platform: linux-64 + dependencies: + python: '' + sphinx: '' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-issues-1.2.0-py_0.tar.bz2 + hash: + md5: 2d5c0dddca9bb724dcf5a3fb295a2266 + sha256: 9d98392bff12194c45c6f13c6c93d0b15b2fe489de5746654e732009fce41a86 + category: main + optional: false +- name: sphinx-issues + version: 1.2.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + sphinx: '' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-issues-1.2.0-py_0.tar.bz2 + hash: + md5: 2d5c0dddca9bb724dcf5a3fb295a2266 + sha256: 9d98392bff12194c45c6f13c6c93d0b15b2fe489de5746654e732009fce41a86 + category: main + optional: false +- name: sphinx-panels + version: 0.6.0 + manager: conda + platform: linux-64 + dependencies: + docutils: '' + python: '>=3.6' + sphinx: '>=2,<5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-panels-0.6.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 6eec6480601f5d15babf9c3b3987f34a + sha256: c6043ff3f25905453f5c11d1620a4bc118a87a3eda02a3041f4ef98d8e6e6389 + category: main + optional: false +- name: sphinx-panels + version: 0.6.0 + manager: conda + platform: osx-arm64 + dependencies: + docutils: '' + python: '>=3.6' + sphinx: '>=2,<5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-panels-0.6.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 6eec6480601f5d15babf9c3b3987f34a + sha256: c6043ff3f25905453f5c11d1620a4bc118a87a3eda02a3041f4ef98d8e6e6389 + category: main + optional: false +- name: sphinx-prompt + version: 1.4.0 + manager: conda + platform: linux-64 + dependencies: + pygments: '' + python: '>=3.0' + sphinx: '' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-prompt-1.4.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 88ee91e8679603f2a5bd036d52919cc2 + sha256: 3690b4b70322adc77f18c2b31545ddbbe69f1627de76ea9deace8c9809550bab + category: main + optional: false +- name: sphinx-prompt + version: 1.4.0 + manager: conda + platform: osx-arm64 + dependencies: + pygments: '' + sphinx: '' + python: '>=3.0' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-prompt-1.4.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 88ee91e8679603f2a5bd036d52919cc2 + sha256: 3690b4b70322adc77f18c2b31545ddbbe69f1627de76ea9deace8c9809550bab + category: main + optional: false +- name: sphinx-tabs + version: 3.4.1 + manager: conda + platform: linux-64 + dependencies: + docutils: '>=0.16.0' + pygments: '' + python: '>=3.6' + sphinx: '>=2,<5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-tabs-3.4.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: b04565a0bfac26170025770fe3256dcd + sha256: 79228ab583277a527456786f2060211bfed2647259b960566af1718d44dae2aa + category: main + optional: false +- name: sphinx-tabs + version: 3.4.1 + manager: conda + platform: osx-arm64 + dependencies: + pygments: '' + python: '>=3.6' + sphinx: '>=2,<5' + docutils: '>=0.16.0' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-tabs-3.4.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: b04565a0bfac26170025770fe3256dcd + sha256: 79228ab583277a527456786f2060211bfed2647259b960566af1718d44dae2aa + category: main + optional: false +- name: sphinx-tags + version: 0.2.1 + manager: conda + platform: linux-64 + dependencies: + pre-commit: '' + python: '>=3.6' + sphinx: '>4' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-tags-0.2.1-pyhd8ed1ab_0.conda + hash: + md5: 690eb6bc03d9154ac1e679d7c861b845 + sha256: 16848eedb611ed28abffc1d8594d07df08659a8135c100c1131a8223b99b556d + category: main + optional: false +- name: sphinx-tags + version: 0.2.1 + manager: conda + platform: osx-arm64 + dependencies: + pre-commit: '' + python: '>=3.6' + sphinx: '>4' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx-tags-0.2.1-pyhd8ed1ab_0.conda + hash: + md5: 690eb6bc03d9154ac1e679d7c861b845 + sha256: 16848eedb611ed28abffc1d8594d07df08659a8135c100c1131a8223b99b556d + category: main + optional: false +- name: sphinx_fontawesome + version: 0.0.6 + manager: conda + platform: linux-64 + dependencies: + python: '' + sphinx: '>=1.5.0' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx_fontawesome-0.0.6-pyh8c360ce_0.tar.bz2 + hash: + md5: fc037d1b4a799959b8770375e6458bfd + sha256: 2125421eada1cbafdc5e0058e07a417f7f6c938b447eb63e80fbe8403e7235e5 + category: main + optional: false +- name: sphinx_fontawesome + version: 0.0.6 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + sphinx: '>=1.5.0' + url: https://conda.anaconda.org/conda-forge/noarch/sphinx_fontawesome-0.0.6-pyh8c360ce_0.tar.bz2 + hash: + md5: fc037d1b4a799959b8770375e6458bfd + sha256: 2125421eada1cbafdc5e0058e07a417f7f6c938b447eb63e80fbe8403e7235e5 + category: main + optional: false +- name: sphinxcontrib-applehelp + version: 1.0.4 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-1.0.4-pyhd8ed1ab_0.conda + hash: + md5: 5a31a7d564f551d0e6dff52fd8cb5b16 + sha256: 802810d8321d55e5666806d565e72949eabf77ad510fe2758ce1da2441675ef1 + category: main + optional: false +- name: sphinxcontrib-applehelp + version: 1.0.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-1.0.4-pyhd8ed1ab_0.conda + hash: + md5: 5a31a7d564f551d0e6dff52fd8cb5b16 + sha256: 802810d8321d55e5666806d565e72949eabf77ad510fe2758ce1da2441675ef1 + category: main + optional: false +- name: sphinxcontrib-devhelp + version: 1.0.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-1.0.2-py_0.tar.bz2 + hash: + md5: 68e01cac9d38d0e717cd5c87bc3d2cc9 + sha256: 66cca7eccb7f92eee53f9f5a552e3e1d643daa3a1ebd03c185e2819e5c491576 + category: main + optional: false +- name: sphinxcontrib-devhelp + version: 1.0.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-1.0.2-py_0.tar.bz2 + hash: + md5: 68e01cac9d38d0e717cd5c87bc3d2cc9 + sha256: 66cca7eccb7f92eee53f9f5a552e3e1d643daa3a1ebd03c185e2819e5c491576 + category: main + optional: false +- name: sphinxcontrib-dotnetdomain + version: '0.4' + manager: conda + platform: linux-64 + dependencies: + python: '' + sphinx: '>=0.6' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-dotnetdomain-0.4-py_0.tar.bz2 + hash: + md5: fb61a7369f505b4bb98e1530c3e09f9f + sha256: bcec8d02205dc27bc399e42513d204f8557b8b06a9546ed784c283086850211c + category: main + optional: false +- name: sphinxcontrib-dotnetdomain + version: '0.4' + manager: conda + platform: osx-arm64 + dependencies: + python: '' + sphinx: '>=0.6' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-dotnetdomain-0.4-py_0.tar.bz2 + hash: + md5: fb61a7369f505b4bb98e1530c3e09f9f + sha256: bcec8d02205dc27bc399e42513d204f8557b8b06a9546ed784c283086850211c + category: main + optional: false +- name: sphinxcontrib-golangdomain + version: 0.2.0.dev0 + manager: conda + platform: linux-64 + dependencies: + python: '' + sphinx: '>=1.0' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-golangdomain-0.2.0.dev0-py_0.tar.bz2 + hash: + md5: d1a73c192888d08cedec232602c22f32 + sha256: 1610ab148559364b6927e481f5c97f31c8130ffcca2dc16d1c4b33c281e408d6 + category: main + optional: false +- name: sphinxcontrib-golangdomain + version: 0.2.0.dev0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + sphinx: '>=1.0' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-golangdomain-0.2.0.dev0-py_0.tar.bz2 + hash: + md5: d1a73c192888d08cedec232602c22f32 + sha256: 1610ab148559364b6927e481f5c97f31c8130ffcca2dc16d1c4b33c281e408d6 + category: main + optional: false +- name: sphinxcontrib-htmlhelp + version: 2.0.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.0.1-pyhd8ed1ab_0.conda + hash: + md5: 6c8c4d6eb2325e59290ac6dbbeacd5f0 + sha256: aeff20be994e6f9520a91fc177a33cb3e4d0911cdf8d27e575d001f00afa33fd + category: main + optional: false +- name: sphinxcontrib-htmlhelp + version: 2.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.0.1-pyhd8ed1ab_0.conda + hash: + md5: 6c8c4d6eb2325e59290ac6dbbeacd5f0 + sha256: aeff20be994e6f9520a91fc177a33cb3e4d0911cdf8d27e575d001f00afa33fd + category: main + optional: false +- name: sphinxcontrib-jsmath + version: 1.0.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda + hash: + md5: da1d979339e2714c30a8e806a33ec087 + sha256: d4337d83b8edba688547766fc80f1ac86d6ec86ceeeda93f376acc04079c5ce2 + category: main + optional: false +- name: sphinxcontrib-jsmath + version: 1.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda + hash: + md5: da1d979339e2714c30a8e806a33ec087 + sha256: d4337d83b8edba688547766fc80f1ac86d6ec86ceeeda93f376acc04079c5ce2 + category: main + optional: false +- name: sphinxcontrib-mermaid + version: 0.9.2 + manager: conda + platform: linux-64 + dependencies: + docutils: '' + python: '>=3.7' + sphinx: '' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-mermaid-0.9.2-pyhd8ed1ab_0.conda + hash: + md5: 54a6a75e5b3989f1d925d8e5674bbbcb + sha256: bb02467bb3569406d978112f299e8d8b0832cc495b8bbd5d591858ddbe3a291d + category: main + optional: false +- name: sphinxcontrib-mermaid + version: 0.9.2 + manager: conda + platform: osx-arm64 + dependencies: + sphinx: '' + docutils: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-mermaid-0.9.2-pyhd8ed1ab_0.conda + hash: + md5: 54a6a75e5b3989f1d925d8e5674bbbcb + sha256: bb02467bb3569406d978112f299e8d8b0832cc495b8bbd5d591858ddbe3a291d + category: main + optional: false +- name: sphinxcontrib-qthelp + version: 1.0.3 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.3-py_0.tar.bz2 + hash: + md5: d01180388e6d1838c3e1ad029590aa7a + sha256: 35d8f01fc798d38b72ae003c040d2dee650d315f904268a1f793d4d59460d1e2 + category: main + optional: false +- name: sphinxcontrib-qthelp + version: 1.0.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.3-py_0.tar.bz2 + hash: + md5: d01180388e6d1838c3e1ad029590aa7a + sha256: 35d8f01fc798d38b72ae003c040d2dee650d315f904268a1f793d4d59460d1e2 + category: main + optional: false +- name: sphinxcontrib-serializinghtml + version: 1.1.5 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.5-pyhd8ed1ab_2.tar.bz2 + hash: + md5: 9ff55a0901cf952f05c654394de76bf7 + sha256: 890bbf815cff114ddbb618b9876d492fce07d02956c1d7b3d46cb7f835f563f6 + category: main + optional: false +- name: sphinxcontrib-serializinghtml + version: 1.1.5 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.5-pyhd8ed1ab_2.tar.bz2 + hash: + md5: 9ff55a0901cf952f05c654394de76bf7 + sha256: 890bbf815cff114ddbb618b9876d492fce07d02956c1d7b3d46cb7f835f563f6 + category: main + optional: false +- name: sphinxcontrib-youtube + version: 1.2.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + requests: '' + sphinx: '>=0.6' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-youtube-1.2.0-pyhd8ed1ab_0.conda + hash: + md5: 08b58a79c8cc29922dd65fff31577008 + sha256: 90e8c853aa0f99ad82ae28f8289f7d56153970bd81dcc9f810ab9ec051d9365a + category: main + optional: false +- name: sphinxcontrib-youtube + version: 1.2.0 + manager: conda + platform: osx-arm64 + dependencies: + requests: '' + python: '>=3.6' + sphinx: '>=0.6' + url: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-youtube-1.2.0-pyhd8ed1ab_0.conda + hash: + md5: 08b58a79c8cc29922dd65fff31577008 + sha256: 90e8c853aa0f99ad82ae28f8289f7d56153970bd81dcc9f810ab9ec051d9365a + category: main + optional: false +- name: sqlalchemy + version: 2.0.23 + manager: conda + platform: linux-64 + dependencies: + greenlet: '!=0.4.17' + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + typing-extensions: '>=4.2.0' + url: https://conda.anaconda.org/conda-forge/linux-64/sqlalchemy-2.0.23-py39hd1e30aa_0.conda + hash: + md5: ad585ef3085a52e4890fe7ea1d2a0606 + sha256: 45ce1f68861b61e21638624f99017c16c53b3abab60691d9c48bf8586681c4e2 + category: main + optional: false +- name: sqlalchemy + version: 2.0.23 + manager: conda + platform: osx-arm64 + dependencies: + greenlet: '!=0.4.17' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + typing-extensions: '>=4.2.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/sqlalchemy-2.0.23-py39h17cfd9d_0.conda + hash: + md5: 8facab2c48a6eebe53d4664e86461e1b + sha256: a020f91d478a9b71080c7d31c9759d43418cf04d438d6b8ed9ef0d7351a1179a + category: main + optional: false +- name: sqlite + version: 3.44.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libsqlite: 3.44.2 + libzlib: '>=1.2.13,<1.3.0a0' + ncurses: '>=6.4,<7.0a0' + readline: '>=8.2,<9.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.44.2-h2c6b66d_0.conda + hash: + md5: 4f2892c672829693fd978d065db4e8be + sha256: bae479520fe770fe11996b4c240923ed097f851fbd2401d55540e551c9dbbef7 + category: main + optional: false +- name: sqlparse + version: 0.4.4 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sqlparse-0.4.4-pyhd8ed1ab_0.conda + hash: + md5: 2e2f31b3b1c866c29636377e14f8c4c6 + sha256: 7972c9b15dafa1885f3d4cd22dc4edea4cd969d12739fb71f8632f2c3350706a + category: main + optional: false +- name: sqlparse + version: 0.4.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/sqlparse-0.4.4-pyhd8ed1ab_0.conda + hash: + md5: 2e2f31b3b1c866c29636377e14f8c4c6 + sha256: 7972c9b15dafa1885f3d4cd22dc4edea4cd969d12739fb71f8632f2c3350706a + category: main + optional: false +- name: stack_data + version: 0.6.2 + manager: conda + platform: linux-64 + dependencies: + asttokens: '' + executing: '' + pure_eval: '' + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda + hash: + md5: e7df0fdd404616638df5ece6e69ba7af + sha256: a58433e75229bec39f3be50c02efbe9b7083e53a1f31d8ee247564f370191eec + category: main + optional: false +- name: stack_data + version: 0.6.2 + manager: conda + platform: osx-arm64 + dependencies: + asttokens: '' + executing: '' + pure_eval: '' + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda + hash: + md5: e7df0fdd404616638df5ece6e69ba7af + sha256: a58433e75229bec39f3be50c02efbe9b7083e53a1f31d8ee247564f370191eec + category: main + optional: false +- name: statsd + version: 3.3.0 + manager: conda + platform: linux-64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/statsd-3.3.0-py_0.tar.bz2 + hash: + md5: 8f5c03d5657905e6c70c3e6e522bfb4e + sha256: 3553501b2981764bdd650d83a8d03886e9ffcbe7930327e5d2043322953da8ca + category: main + optional: false +- name: statsd + version: 3.3.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/statsd-3.3.0-py_0.tar.bz2 + hash: + md5: 8f5c03d5657905e6c70c3e6e522bfb4e + sha256: 3553501b2981764bdd650d83a8d03886e9ffcbe7930327e5d2043322953da8ca + category: main + optional: false +- name: stringcase + version: 1.2.0 + manager: conda + platform: linux-64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/stringcase-1.2.0-py_0.tar.bz2 + hash: + md5: 26a9caf3173939377bac7152379daac0 + sha256: ebd515c57537799ee7829055fe9aa93d1c4695334b991fe1de9d7947f53f18f2 + category: main + optional: false +- name: stringcase + version: 1.2.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/stringcase-1.2.0-py_0.tar.bz2 + hash: + md5: 26a9caf3173939377bac7152379daac0 + sha256: ebd515c57537799ee7829055fe9aa93d1c4695334b991fe1de9d7947f53f18f2 + category: main + optional: false +- name: sympy + version: '1.12' + manager: conda + platform: linux-64 + dependencies: + __unix: '' + gmpy2: '>=2.0.8' + mpmath: '>=0.19' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/sympy-1.12-pypyh9d50eac_103.conda + hash: + md5: 2f7d6347d7acf6edf1ac7f2189f44c8f + sha256: 0025dd4e6411423903bf478d1b9fbff0cbbbe546f51c9375dfd6729ef2e1a1ac + category: main + optional: false +- name: sympy + version: '1.12' + manager: conda + platform: osx-arm64 + dependencies: + __unix: '' + python: '*' + mpmath: '>=0.19' + gmpy2: '>=2.0.8' + url: https://conda.anaconda.org/conda-forge/noarch/sympy-1.12-pypyh9d50eac_103.conda + hash: + md5: 2f7d6347d7acf6edf1ac7f2189f44c8f + sha256: 0025dd4e6411423903bf478d1b9fbff0cbbbe546f51c9375dfd6729ef2e1a1ac + category: main + optional: false +- name: tabulate + version: 0.9.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_1.tar.bz2 + hash: + md5: 4759805cce2d914c38472f70bf4d8bcb + sha256: f6e4a0dd24ba060a4af69ca79d32361a6678e61d78c73eb5e357909b025b4620 + category: main + optional: false +- name: tabulate + version: 0.9.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_1.tar.bz2 + hash: + md5: 4759805cce2d914c38472f70bf4d8bcb + sha256: f6e4a0dd24ba060a4af69ca79d32361a6678e61d78c73eb5e357909b025b4620 + category: main + optional: false +- name: tbb + version: 2021.10.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libhwloc: '>=2.9.3,<2.9.4.0a0' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.10.0-h00ab1b0_2.conda + hash: + md5: eb0d5c122f42714f86a7058d1ce7b2e6 + sha256: 79a6c48fa1df661af7ab3e4f5fa444dd305d87921be017413a8b97fd6d642328 + category: main + optional: false +- name: tblib + version: 2.0.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tblib-2.0.0-pyhd8ed1ab_0.conda + hash: + md5: f5580336fe091d46f9a2ea97da044550 + sha256: 25557d772df1572e48e4c678d5825ace6411d7b6773f2d7ad4e06111bce12031 + category: main + optional: false +- name: tblib + version: 2.0.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tblib-2.0.0-pyhd8ed1ab_0.conda + hash: + md5: f5580336fe091d46f9a2ea97da044550 + sha256: 25557d772df1572e48e4c678d5825ace6411d7b6773f2d7ad4e06111bce12031 + category: main + optional: false +- name: tenacity + version: 8.2.3 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.2.3-pyhd8ed1ab_0.conda + hash: + md5: 1482e77f87c6a702a7e05ef22c9b197b + sha256: 860c11e7369d6a86fcc9c6cbca49d5c457f6c0a27faeacca4d46267f9dd10d78 + category: main + optional: false +- name: tenacity + version: 8.2.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.2.3-pyhd8ed1ab_0.conda + hash: + md5: 1482e77f87c6a702a7e05ef22c9b197b + sha256: 860c11e7369d6a86fcc9c6cbca49d5c457f6c0a27faeacca4d46267f9dd10d78 + category: main + optional: false +- name: tensorboard + version: 2.14.1 + manager: conda + platform: linux-64 + dependencies: + absl-py: '>=0.4' + google-auth: '>=1.6.3,<3' + google-auth-oauthlib: '>=0.5,<1.1' + grpcio: '>=1.48.2' + markdown: '>=2.6.8' + numpy: '>=1.12.0' + protobuf: '>=3.19.6' + python: '>=3.8' + requests: '>=2.21.0,<3' + setuptools: '>=41.0.0' + six: '>=1.9' + tensorboard-data-server: '>=0.7.0,<0.8.0' + werkzeug: '>=1.0.1' + url: https://conda.anaconda.org/conda-forge/noarch/tensorboard-2.14.1-pyhd8ed1ab_0.conda + hash: + md5: fd77b4ee10b417788c0026de58568d01 + sha256: 19d91a20089855c613f3cf73bd72facab9f666539971bb69280c075c97c6491a + category: main + optional: false +- name: tensorboard + version: 2.14.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + six: '>=1.9' + numpy: '>=1.12.0' + setuptools: '>=41.0.0' + markdown: '>=2.6.8' + absl-py: '>=0.4' + requests: '>=2.21.0,<3' + werkzeug: '>=1.0.1' + google-auth: '>=1.6.3,<3' + grpcio: '>=1.48.2' + protobuf: '>=3.19.6' + tensorboard-data-server: '>=0.7.0,<0.8.0' + google-auth-oauthlib: '>=0.5,<1.1' + url: https://conda.anaconda.org/conda-forge/noarch/tensorboard-2.14.1-pyhd8ed1ab_0.conda + hash: + md5: fd77b4ee10b417788c0026de58568d01 + sha256: 19d91a20089855c613f3cf73bd72facab9f666539971bb69280c075c97c6491a + category: main + optional: false +- name: tensorboard-data-server + version: 0.7.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + openssl: '>=3.1.3,<4.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/tensorboard-data-server-0.7.0-py39hd4f0224_1.conda + hash: + md5: 385936ccbb943d2be60177871c1c0bb5 + sha256: 0389876d33062d7859a8078e6658569ea5df7a06206852c8dd02314e0db170b5 + category: main + optional: false +- name: tensorboard-data-server + version: 0.7.0 + manager: conda + platform: osx-arm64 + dependencies: + openssl: '>=3.1.3,<4.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/tensorboard-data-server-0.7.0-py39had97604_1.conda + hash: + md5: dacefd6d65ec1e5aac14d2607aba59ed + sha256: dc9b5fc5f5b1cbea2544a73b5e578c200210438fd5cb669c6dfd64e21c9e3c7f + category: main + optional: false +- name: tensorflow + version: 2.14.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + tensorflow-base: 2.14.0 + tensorflow-estimator: 2.14.0 + url: https://conda.anaconda.org/conda-forge/linux-64/tensorflow-2.14.0-cpu_py39h4655687_0.conda + hash: + md5: 2b69c2c80e61a9bfe86a9e9b78ff4ba7 + sha256: 140178c0a7ad4323a3a03a8fbc5f3228dd8d45d6c21661a30a385356f852d0b3 + category: main + optional: false +- name: tensorflow + version: 2.14.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + tensorflow-base: 2.14.0 + tensorflow-estimator: 2.14.0 + url: https://conda.anaconda.org/conda-forge/osx-arm64/tensorflow-2.14.0-cpu_py39h2839aeb_0.conda + hash: + md5: b493f70acef9bd0b5883a3cdc3a308f6 + sha256: 2fb43d6c4f168ff4e51b3b5258db49b3c47c4da8984e398e317a137975f77ae2 + category: main + optional: false +- name: tensorflow-base + version: 2.14.0 + manager: conda + platform: linux-64 + dependencies: + absl-py: '>=1.0.0' + astunparse: '>=1.6.0' + flatbuffers: '>=23.5.26,<23.5.27.0a0' + gast: '>=0.2.1,!=0.5.0,!=0.5.1,!=0.5.2' + giflib: '>=5.2.1,<5.3.0a0' + google-pasta: '>=0.1.1' + grpcio: 1.54.* + h5py: '>=2.9.0' + icu: '>=73.2,<74.0a0' + keras: '>=2.14,<2.15' + libabseil: '>=20230125.3,<20230126.0a0' + libcurl: '>=8.4.0,<9.0a0' + libgcc-ng: '>=12' + libgrpc: '>=1.54.3,<1.55.0a0' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libprotobuf: '>=3.21.12,<3.22.0a0' + libsqlite: '>=3.44.0,<4.0a0' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + ml_dtypes: 0.2.0.* + numpy: '>=1.22.4,<2.0a0' + openssl: '>=3.1.4,<4.0a0' + opt_einsum: '>=2.3.2' + packaging: '' + protobuf: '>=3.20.3,<5,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5' + python: '>=3.9,<3.10.0a0' + python-flatbuffers: '>=23.5.26' + python_abi: 3.9.* + six: '>=1.12' + snappy: '>=1.1.10,<2.0a0' + tensorboard: '>=2.14,<2.15' + termcolor: '>=1.1.0' + typing_extensions: '>=3.6.6' + wrapt: '>=1.11.0,<1.15' + url: https://conda.anaconda.org/conda-forge/linux-64/tensorflow-base-2.14.0-cpu_py39h65ed569_0.conda + hash: + md5: da26d8c9430738ef95213bf143467748 + sha256: a13ee6d37ea23cc2c31b8bbec609d9384280fd1545eda02f5dfb46ce69a3d6f0 + category: main + optional: false +- name: tensorflow-base + version: 2.14.0 + manager: conda + platform: osx-arm64 + dependencies: + absl-py: '>=1.0.0' + astunparse: '>=1.6.0' + flatbuffers: '>=23.5.26,<23.5.27.0a0' + gast: '>=0.2.1,!=0.5.0,!=0.5.1,!=0.5.2' + giflib: '>=5.2.1,<5.3.0a0' + google-pasta: '>=0.1.1' + grpcio: 1.54.* + h5py: '>=2.9.0' + icu: '>=73.2,<74.0a0' + keras: '>=2.14,<2.15' + libabseil: '>=20230125.3,<20230126.0a0' + libcurl: '>=8.4.0,<9.0a0' + libcxx: '>=16.0.6' + libgrpc: '>=1.54.3,<1.55.0a0' + libjpeg-turbo: '>=3.0.0,<4.0a0' + libpng: '>=1.6.39,<1.7.0a0' + libprotobuf: '>=3.21.12,<3.22.0a0' + libsqlite: '>=3.44.0,<4.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + ml_dtypes: 0.2.0.* + numpy: '>=1.22.4,<2.0a0' + openssl: '>=3.1.4,<4.0a0' + opt_einsum: '>=2.3.2' + packaging: '' + protobuf: '>=3.20.3,<5,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5' + python: '>=3.9,<3.10.0a0' + python-flatbuffers: '>=23.5.26' + python_abi: 3.9.* + six: '>=1.12' + snappy: '>=1.1.10,<2.0a0' + tensorboard: '>=2.14,<2.15' + termcolor: '>=1.1.0' + typing_extensions: '>=3.6.6' + wrapt: '>=1.11.0,<1.15' + url: https://conda.anaconda.org/conda-forge/osx-arm64/tensorflow-base-2.14.0-cpu_py39ha6a491e_0.conda + hash: + md5: 8400feabaf44f32247a9bc82b659afb7 + sha256: e2cefe1d85c5b9e10b35515adfd408df5585f64920dc84aa9bf62fba4c1cb4d9 + category: main + optional: false +- name: tensorflow-estimator + version: 2.14.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + openssl: '>=3.1.4,<4.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + tensorflow-base: 2.14.0 + url: https://conda.anaconda.org/conda-forge/linux-64/tensorflow-estimator-2.14.0-cpu_py39hd56b5fd_0.conda + hash: + md5: 01e077379807b9b0d703c68cd0b38c50 + sha256: 24593e6b59600e1a0c9340eeaa406d9b77ee04d7c9d349aef1020f625f872f09 + category: main + optional: false +- name: tensorflow-estimator + version: 2.14.0 + manager: conda + platform: osx-arm64 + dependencies: + libcxx: '>=16.0.6' + openssl: '>=3.1.4,<4.0a0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + tensorflow-base: 2.14.0 + url: https://conda.anaconda.org/conda-forge/osx-arm64/tensorflow-estimator-2.14.0-cpu_py39ha1daed2_0.conda + hash: + md5: 080a34a0c9508f7b877e4e4bed648f7f + sha256: a370bf33e2309f0e98b298ed6a8bd90f8cf2b7662fe85c03822dbef627f18618 + category: main + optional: false +- name: termcolor + version: 2.3.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/termcolor-2.3.0-pyhd8ed1ab_0.conda + hash: + md5: 440d508f025b1692168caaf436504af3 + sha256: db8c38777093d87fc05dc3f57d26c171c4e4896f17a013c6f839050c989a759e + category: main + optional: false +- name: termcolor + version: 2.3.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/termcolor-2.3.0-pyhd8ed1ab_0.conda + hash: + md5: 440d508f025b1692168caaf436504af3 + sha256: db8c38777093d87fc05dc3f57d26c171c4e4896f17a013c6f839050c989a759e + category: main + optional: false +- name: terminado + version: 0.18.0 + manager: conda + platform: linux-64 + dependencies: + __linux: '' + ptyprocess: '' + python: '>=3.8' + tornado: '>=6.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.0-pyh0d859eb_0.conda + hash: + md5: e463f348b8b0eb62c9f7c6fbc780286c + sha256: e90139ef15ea9d75a69cd6b6302c29ed5b01c03ddfa717b71acb32b60af74269 + category: main + optional: false +- name: terminado + version: 0.18.0 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '' + ptyprocess: '' + python: '>=3.8' + tornado: '>=6.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.0-pyh31c8845_0.conda + hash: + md5: 14759b57f5b9d97033e633fff0a2d27e + sha256: 8e8741c688ade9be8f86c0b209780c7fbe4a97e4265311ca9d8dda5fcedc6a28 + category: main + optional: false +- name: text-unidecode + version: '1.3' + manager: conda + platform: linux-64 + dependencies: + python: '>=3.4' + url: https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_1.conda + hash: + md5: ba8aba332d8868897ce44ad74015a7fe + sha256: db64669a918dec8c744f80a85b9c82216b79298256c7c8bd19bdba54a02f8914 + category: main + optional: false +- name: text-unidecode + version: '1.3' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.4' + url: https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_1.conda + hash: + md5: ba8aba332d8868897ce44ad74015a7fe + sha256: db64669a918dec8c744f80a85b9c82216b79298256c7c8bd19bdba54a02f8914 + category: main + optional: false +- name: textwrap3 + version: 0.9.2 + manager: conda + platform: linux-64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/textwrap3-0.9.2-py_0.tar.bz2 + hash: + md5: 1f84e74e9dbe2e5ae38c58496bffaca8 + sha256: d7b40d3a3f1c2e74bbea5ee845b34a30abc1ae8e4f2a92f4a58800e1e669c076 + category: main + optional: false +- name: textwrap3 + version: 0.9.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '' + url: https://conda.anaconda.org/conda-forge/noarch/textwrap3-0.9.2-py_0.tar.bz2 + hash: + md5: 1f84e74e9dbe2e5ae38c58496bffaca8 + sha256: d7b40d3a3f1c2e74bbea5ee845b34a30abc1ae8e4f2a92f4a58800e1e669c076 + category: main + optional: false +- name: tf2onnx + version: 1.15.1 + manager: conda + platform: linux-64 + dependencies: + numpy: '>=1.14.1' + onnx: '>=1.4.1' + python: '>=3.8' + python-flatbuffers: '>=1.12' + requests: '' + six: '' + tensorflow: '>=2.6' + url: https://conda.anaconda.org/conda-forge/noarch/tf2onnx-1.15.1-pyhd8ed1ab_1.conda + hash: + md5: 41a891ad34703e0ebc2d36098b8bbe56 + sha256: 403f37c0c4881d11fbb63573c542105d9d1165294f35b1491143085c76aa5160 + category: main + optional: false +- name: tf2onnx + version: 1.15.1 + manager: conda + platform: osx-arm64 + dependencies: + requests: '' + six: '' + python: '>=3.8' + numpy: '>=1.14.1' + tensorflow: '>=2.6' + python-flatbuffers: '>=1.12' + onnx: '>=1.4.1' + url: https://conda.anaconda.org/conda-forge/noarch/tf2onnx-1.15.1-pyhd8ed1ab_1.conda + hash: + md5: 41a891ad34703e0ebc2d36098b8bbe56 + sha256: 403f37c0c4881d11fbb63573c542105d9d1165294f35b1491143085c76aa5160 + category: main + optional: false +- name: threadpoolctl + version: 3.2.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.2.0-pyha21a80b_0.conda + hash: + md5: 978d03388b62173b8e6f79162cf52b86 + sha256: 15e2f916fbfe3cc480160aa99eb6ba3edc183fceb234f10151d63870fdc4eccd + category: main + optional: false +- name: threadpoolctl + version: 3.2.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.2.0-pyha21a80b_0.conda + hash: + md5: 978d03388b62173b8e6f79162cf52b86 + sha256: 15e2f916fbfe3cc480160aa99eb6ba3edc183fceb234f10151d63870fdc4eccd + category: main + optional: false +- name: tiledb + version: 2.16.3 + manager: conda + platform: linux-64 + dependencies: + bzip2: '>=1.0.8,<2.0a0' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + libxml2: '>=2.11.5,<2.12.0a0' + libzlib: '>=1.2.13,<1.3.0a0' + lz4-c: '>=1.9.3,<1.10.0a0' + openssl: '>=3.1.2,<4.0a0' + zstd: '>=1.5.5,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/tiledb-2.16.3-hf0b6e87_3.conda + hash: + md5: 1e28da846782f91a696af3952a2472f9 + sha256: 6755c8dde4ea401d2c312dbb1dd2b4632bbac59851375182728ac8d5894acbd8 + category: main + optional: false +- name: tinycss2 + version: 1.2.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + webencodings: '>=0.4' + url: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.2.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 7234c9eefff659501cd2fe0d2ede4d48 + sha256: f0db1a2298a5e10e30f4b947566c7229442834702f549dded40a73ecdea7502d + category: main + optional: false +- name: tinycss2 + version: 1.2.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + webencodings: '>=0.4' + url: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.2.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 7234c9eefff659501cd2fe0d2ede4d48 + sha256: f0db1a2298a5e10e30f4b947566c7229442834702f549dded40a73ecdea7502d + category: main + optional: false +- name: tk + version: 8.6.13 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda + hash: + md5: d453b98d9c83e71da0741bb0ff4d76bc + sha256: e0569c9caa68bf476bead1bed3d79650bb080b532c64a4af7d8ca286c08dea4e + category: main + optional: false +- name: tk + version: 8.6.13 + manager: conda + platform: osx-arm64 + dependencies: + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda + hash: + md5: b50a57ba89c32b62428b71a875291c9b + sha256: 72457ad031b4c048e5891f3f6cb27a53cb479db68a52d965f796910e71a403a8 + category: main + optional: false +- name: toml + version: 0.10.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: f832c45a477c78bebd107098db465095 + sha256: f0f3d697349d6580e4c2f35ba9ce05c65dc34f9f049e85e45da03800b46139c1 + category: main + optional: false +- name: toml + version: 0.10.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=2.7' + url: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 + hash: + md5: f832c45a477c78bebd107098db465095 + sha256: f0f3d697349d6580e4c2f35ba9ce05c65dc34f9f049e85e45da03800b46139c1 + category: main + optional: false +- name: tomli + version: 2.0.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 5844808ffab9ebdb694585b50ba02a96 + sha256: 4cd48aba7cd026d17e86886af48d0d2ebc67ed36f87f6534f4b67138f5a5a58f + category: main + optional: false +- name: tomli + version: 2.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 5844808ffab9ebdb694585b50ba02a96 + sha256: 4cd48aba7cd026d17e86886af48d0d2ebc67ed36f87f6534f4b67138f5a5a58f + category: main + optional: false +- name: tomlkit + version: 0.12.3 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.12.3-pyha770c72_0.conda + hash: + md5: 074d0ce7a6261ab8b497c3518796ef3e + sha256: 53cc436ab92d38683df1320e4468a8b978428e800195bf1c8c2460e90b0bc117 + category: main + optional: false +- name: tomlkit + version: 0.12.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.12.3-pyha770c72_0.conda + hash: + md5: 074d0ce7a6261ab8b497c3518796ef3e + sha256: 53cc436ab92d38683df1320e4468a8b978428e800195bf1c8c2460e90b0bc117 + category: main + optional: false +- name: toolz + version: 0.12.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 92facfec94bc02d6ccf42e7173831a36 + sha256: 90229da7665175b0185183ab7b53f50af487c7f9b0f47cf09c184cbc139fd24b + category: main + optional: false +- name: toolz + version: 0.12.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 92facfec94bc02d6ccf42e7173831a36 + sha256: 90229da7665175b0185183ab7b53f50af487c7f9b0f47cf09c184cbc139fd24b + category: main + optional: false +- name: tornado + version: 6.3.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.3.3-py39hd1e30aa_1.conda + hash: + md5: cbe186eefb0bcd91e8f47c3908489874 + sha256: dc0df742be0e83a4286137d21f60ca829632c2ffd66d3bebb603afe5ce74cc68 + category: main + optional: false +- name: tornado + version: 6.3.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.3.3-py39h0f82c59_1.conda + hash: + md5: 6e7376dbfbe98b5537bfc9a1b8cf1e41 + sha256: e294cd0a32c14e6e879a202a50ae2ad393dd93e767b3f8e54be96cbcf32af595 + category: main + optional: false +- name: tqdm + version: 4.66.1 + manager: conda + platform: linux-64 + dependencies: + colorama: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.1-pyhd8ed1ab_0.conda + hash: + md5: 03c97908b976498dcae97eb4e4f3149c + sha256: b61c9222af05e8c5ff27e4a4d2eb81870c21ffd7478346be3ef644b7a3759cc4 + category: main + optional: false +- name: tqdm + version: 4.66.1 + manager: conda + platform: osx-arm64 + dependencies: + colorama: '' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.1-pyhd8ed1ab_0.conda + hash: + md5: 03c97908b976498dcae97eb4e4f3149c + sha256: b61c9222af05e8c5ff27e4a4d2eb81870c21ffd7478346be3ef644b7a3759cc4 + category: main + optional: false +- name: traitlets + version: 5.14.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.0-pyhd8ed1ab_0.conda + hash: + md5: 886f4a84ddb49b943b1697ac314e85b3 + sha256: c32412029033264140926be474d327d7fd57c0d11db9b1745396b3d4db78a799 + category: main + optional: false +- name: traitlets + version: 5.14.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.0-pyhd8ed1ab_0.conda + hash: + md5: 886f4a84ddb49b943b1697ac314e85b3 + sha256: c32412029033264140926be474d327d7fd57c0d11db9b1745396b3d4db78a799 + category: main + optional: false +- name: typeguard + version: 4.1.5 + manager: conda + platform: linux-64 + dependencies: + importlib_metadata: '>=3.6' + python: '>=3.8' + typing_extensions: '>=4.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.1.5-pyhd8ed1ab_1.conda + hash: + md5: 59d22e0ca481b057b94d54fc9ebacb13 + sha256: df63f90625d2eaefcb6990437b941c1c90ec3c224bc65a2becac928542d0aa5f + category: main + optional: false +- name: typeguard + version: 4.1.5 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + importlib_metadata: '>=3.6' + typing_extensions: '>=4.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.1.5-pyhd8ed1ab_1.conda + hash: + md5: 59d22e0ca481b057b94d54fc9ebacb13 + sha256: df63f90625d2eaefcb6990437b941c1c90ec3c224bc65a2becac928542d0aa5f + category: main + optional: false +- name: types-python-dateutil + version: 2.8.19.14 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.8.19.14-pyhd8ed1ab_0.conda + hash: + md5: 4df15c51a543e806d439490b862be1c6 + sha256: 7b0129c72d371fa7a06ed5dd1d701844c20d03bb4641a38a88a982b347d087e2 + category: main + optional: false +- name: types-python-dateutil + version: 2.8.19.14 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.8.19.14-pyhd8ed1ab_0.conda + hash: + md5: 4df15c51a543e806d439490b862be1c6 + sha256: 7b0129c72d371fa7a06ed5dd1d701844c20d03bb4641a38a88a982b347d087e2 + category: main + optional: false +- name: typing-extensions + version: 4.8.0 + manager: conda + platform: linux-64 + dependencies: + typing_extensions: 4.8.0 + url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.8.0-hd8ed1ab_0.conda + hash: + md5: 384462e63262a527bda564fa2d9126c0 + sha256: d6e1dddd0c372218ef15912383d351ac8c73465cbf16238017f0269813cafe2d + category: main + optional: false +- name: typing-extensions + version: 4.8.0 + manager: conda + platform: osx-arm64 + dependencies: + typing_extensions: 4.8.0 + url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.8.0-hd8ed1ab_0.conda + hash: + md5: 384462e63262a527bda564fa2d9126c0 + sha256: d6e1dddd0c372218ef15912383d351ac8c73465cbf16238017f0269813cafe2d + category: main + optional: false +- name: typing_extensions + version: 4.8.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.8.0-pyha770c72_0.conda + hash: + md5: 5b1be40a26d10a06f6d4f1f9e19fa0c7 + sha256: 38d16b5c53ec1af845d37d22e7bb0e6c934c7f19499123507c5a470f6f8b7dde + category: main + optional: false +- name: typing_extensions + version: 4.8.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.8.0-pyha770c72_0.conda + hash: + md5: 5b1be40a26d10a06f6d4f1f9e19fa0c7 + sha256: 38d16b5c53ec1af845d37d22e7bb0e6c934c7f19499123507c5a470f6f8b7dde + category: main + optional: false +- name: typing_inspect + version: 0.9.0 + manager: conda + platform: linux-64 + dependencies: + mypy_extensions: '>=0.3.0' + python: '>=3.5' + typing_extensions: '>=3.7.4' + url: https://conda.anaconda.org/conda-forge/noarch/typing_inspect-0.9.0-pyhd8ed1ab_0.conda + hash: + md5: 9e924b76b91908a17e28a19a0ab88687 + sha256: 16e0b825c138e14ebc84623248d91d93a8cff29bb93595cc4aa46ca32f24f1de + category: main + optional: false +- name: typing_inspect + version: 0.9.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + typing_extensions: '>=3.7.4' + mypy_extensions: '>=0.3.0' + url: https://conda.anaconda.org/conda-forge/noarch/typing_inspect-0.9.0-pyhd8ed1ab_0.conda + hash: + md5: 9e924b76b91908a17e28a19a0ab88687 + sha256: 16e0b825c138e14ebc84623248d91d93a8cff29bb93595cc4aa46ca32f24f1de + category: main + optional: false +- name: typing_utils + version: 0.1.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6.1' + url: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: eb67e3cace64c66233e2d35949e20f92 + sha256: 9e3758b620397f56fb709f796969de436d63b7117897159619b87938e1f78739 + category: main + optional: false +- name: typing_utils + version: 0.1.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6.1' + url: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_0.tar.bz2 + hash: + md5: eb67e3cace64c66233e2d35949e20f92 + sha256: 9e3758b620397f56fb709f796969de436d63b7117897159619b87938e1f78739 + category: main + optional: false +- name: tzcode + version: 2023c + manager: conda + platform: linux-64 + dependencies: + __glibc: '>=2.17,<3.0.a0' + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/tzcode-2023c-h0b41bf4_0.conda + hash: + md5: 0c0533894f21c3d35697cb8378d390e2 + sha256: 62b0d3eee4260d310f578015305834b8a588377f796e5e290ec267da8a51a027 + category: main + optional: false +- name: tzdata + version: 2023c + manager: conda + platform: linux-64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/tzdata-2023c-h71feb2d_0.conda + hash: + md5: 939e3e74d8be4dac89ce83b20de2492a + sha256: 0449138224adfa125b220154408419ec37c06b0b49f63c5954724325903ecf55 + category: main + optional: false +- name: tzdata + version: 2023c + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/tzdata-2023c-h71feb2d_0.conda + hash: + md5: 939e3e74d8be4dac89ce83b20de2492a + sha256: 0449138224adfa125b220154408419ec37c06b0b49f63c5954724325903ecf55 + category: main + optional: false +- name: tzlocal + version: '5.2' + manager: conda + platform: linux-64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/tzlocal-5.2-py39hf3d152e_0.conda + hash: + md5: 7d18ee59145954fa918e7a4cb5ef4847 + sha256: 265e13afdb42de545e0d0b9752d1bc8b128ed6b27089347ec42da4803dde2519 + category: main + optional: false +- name: tzlocal + version: '5.2' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/tzlocal-5.2-py39h2804cbe_0.conda + hash: + md5: c4b282fbbd501efef09ff57dcf897f2b + sha256: 8297d3523e496692ce14047f44c3390417efa20000006f4f29f3292d2c4525c2 + category: main + optional: false +- name: ucx + version: 1.14.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libnuma: '>=2.0.16,<3.0a0' + libstdcxx-ng: '>=12' + rdma-core: '>=28.9,<29.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/ucx-1.14.1-h64cca9d_5.conda + hash: + md5: 39aa3b356d10d7e5add0c540945a0944 + sha256: a62f3fb56849dc37270f9078e1c8ba32328bc3ba4d32cf1f7dace48b431d5abe + category: main + optional: false +- name: ukkonen + version: 1.0.1 + manager: conda + platform: linux-64 + dependencies: + cffi: '' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.0.1-py39h7633fee_4.conda + hash: + md5: b66595fbda99771266f042f42c7457be + sha256: 6ca31e79eeee63ea33e5b18dd81c1bc202c43741b5f0de3bcd4409f9ffd93a95 + category: main + optional: false +- name: ukkonen + version: 1.0.1 + manager: conda + platform: osx-arm64 + dependencies: + cffi: '' + libcxx: '>=15.0.7' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.0.1-py39hbd775c9_4.conda + hash: + md5: 1c2db28b464d0331fc4e79796b25c389 + sha256: 2e497466d784c9d2ae94a9e72da05f5b125654ca95d0c0e6c4c697fc5f8be640 + category: main + optional: false +- name: unicodedata2 + version: 15.1.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-15.1.0-py39hd1e30aa_0.conda + hash: + md5: 1da984bbb6e765743e13388ba7b7b2c8 + sha256: 90077cbf116112d5112b7beedf896e59c98416d09860ba98c06a770c014829b2 + category: main + optional: false +- name: unicodedata2 + version: 15.1.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-15.1.0-py39h0f82c59_0.conda + hash: + md5: 39c745ba9443da902afa7f5a9e9dfcac + sha256: 31d33f967f0db811b25a9315bef727cb12a24c76d8ded8947188cc04535b06b0 + category: main + optional: false +- name: unidecode + version: 1.3.7 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/unidecode-1.3.7-pyhd8ed1ab_0.conda + hash: + md5: 06532129755273a6d5a0e0cd179330a5 + sha256: 6f6012c9103324680b8cfa666dd42b9de1da942520b3dc223fda3a43021d6189 + category: main + optional: false +- name: unidecode + version: 1.3.7 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/unidecode-1.3.7-pyhd8ed1ab_0.conda + hash: + md5: 06532129755273a6d5a0e0cd179330a5 + sha256: 6f6012c9103324680b8cfa666dd42b9de1da942520b3dc223fda3a43021d6189 + category: main + optional: false +- name: uri-template + version: 1.3.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_0.conda + hash: + md5: 0944dc65cb4a9b5b68522c3bb585d41c + sha256: b76904b53721dc88a46352324c79d2b077c2f74a9f7208ad2c4249892669ae94 + category: main + optional: false +- name: uri-template + version: 1.3.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_0.conda + hash: + md5: 0944dc65cb4a9b5b68522c3bb585d41c + sha256: b76904b53721dc88a46352324c79d2b077c2f74a9f7208ad2c4249892669ae94 + category: main + optional: false +- name: uriparser + version: 0.9.7 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/uriparser-0.9.7-hcb278e6_1.conda + hash: + md5: 2c46deb08ba9b10e90d0a6401ad65deb + sha256: bc7670384fc3e519b376eab25b2c747afe392b243f17e881075231f4a0f2e5a0 + category: main + optional: false +- name: urllib3 + version: 1.26.18 + manager: conda + platform: linux-64 + dependencies: + brotli-python: '>=1.0.9' + pysocks: '>=1.5.6,<2.0,!=1.5.7' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/urllib3-1.26.18-pyhd8ed1ab_0.conda + hash: + md5: bf61cfd2a7f212efba378167a07d4a6a + sha256: 1cc0bab65a6ad0f5a8bd7657760a4fb4e670d30377f9dab88b792977cb3687e7 + category: main + optional: false +- name: urllib3 + version: 1.26.18 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + brotli-python: '>=1.0.9' + pysocks: '>=1.5.6,<2.0,!=1.5.7' + url: https://conda.anaconda.org/conda-forge/noarch/urllib3-1.26.18-pyhd8ed1ab_0.conda + hash: + md5: bf61cfd2a7f212efba378167a07d4a6a + sha256: 1cc0bab65a6ad0f5a8bd7657760a4fb4e670d30377f9dab88b792977cb3687e7 + category: main + optional: false +- name: vaex-core + version: 4.17.1 + manager: conda + platform: linux-64 + dependencies: + aplus: '' + blake3: '' + cloudpickle: '' + dask: '' + filelock: '' + frozendict: '' + future: '>=0.15.2' + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + nest-asyncio: '>=1.3.3' + numpy: '>=1.21.6,<2.0a0' + pandas: '' + pcre: '>=8.45,<9.0a0' + progressbar2: '' + pyarrow: '>=3.0' + pydantic: '>=1.8.0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + pyyaml: '' + requests: '' + rich: '' + six: '' + tabulate: '>=0.8.3' + url: https://conda.anaconda.org/conda-forge/linux-64/vaex-core-4.17.1-py39h51a5c22_0.conda + hash: + md5: eb55dbc1f7fb59823b361f92ba73f7fa + sha256: b85bf700aac63cafae0d728f36ab35848fdb390be973232d74d61edef78fdcea + category: main + optional: false +- name: vaex-core + version: 4.17.1 + manager: conda + platform: osx-arm64 + dependencies: + aplus: '' + blake3: '' + cloudpickle: '' + dask: '' + filelock: '' + frozendict: '' + future: '>=0.15.2' + libcxx: '>=15.0.7' + nest-asyncio: '>=1.3.3' + numpy: '>=1.21.6,<2.0a0' + pandas: '' + pcre: '>=8.45,<9.0a0' + progressbar2: '' + pyarrow: '>=3.0' + pydantic: '>=1.8.0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + pyyaml: '' + requests: '' + rich: '' + six: '' + tabulate: '>=0.8.3' + url: https://conda.anaconda.org/conda-forge/osx-arm64/vaex-core-4.17.1-py39h173e63b_0.conda + hash: + md5: 3dad97c1d3e0fe8d7f184e22218b0379 + sha256: cbd7399344f0ce694393d31c74a85e074f630c7a9462d203041cb1fc9c619ab5 + category: main + optional: false +- name: virtualenv + version: 20.24.1 + manager: conda + platform: linux-64 + dependencies: + distlib: <1,>=0.3.6 + filelock: <4,>=3.12 + platformdirs: <4,>=3.5.1 + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.24.1-pyhd8ed1ab_0.conda + hash: + md5: 428f6c7385636d72191cb4fa0e489503 + sha256: 462b2277ec75babc2ee69a24a74e673ac633f6056889ed8e54d111f770c40904 + category: main + optional: false +- name: virtualenv + version: 20.24.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + distlib: <1,>=0.3.6 + filelock: <4,>=3.12 + platformdirs: <4,>=3.5.1 + url: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.24.1-pyhd8ed1ab_0.conda + hash: + md5: 428f6c7385636d72191cb4fa0e489503 + sha256: 462b2277ec75babc2ee69a24a74e673ac633f6056889ed8e54d111f770c40904 + category: main + optional: false +- name: wcwidth + version: 0.2.12 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.12-pyhd8ed1ab_0.conda + hash: + md5: bf4a1d1a97ca27b0b65bacd9e238b484 + sha256: ca757d0fc2dbd422af9d3238a8b4b630a6e11df3707a447bd89540656770d1d7 + category: main + optional: false +- name: wcwidth + version: 0.2.12 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.12-pyhd8ed1ab_0.conda + hash: + md5: bf4a1d1a97ca27b0b65bacd9e238b484 + sha256: ca757d0fc2dbd422af9d3238a8b4b630a6e11df3707a447bd89540656770d1d7 + category: main + optional: false +- name: webcolors + version: '1.13' + manager: conda + platform: linux-64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda + hash: + md5: 166212fe82dad8735550030488a01d03 + sha256: 6e097d5fe92849ad3af2c2a313771ad2fbf1cadd4dc4afd552303b2bf3f85211 + category: main + optional: false +- name: webcolors + version: '1.13' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.5' + url: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda + hash: + md5: 166212fe82dad8735550030488a01d03 + sha256: 6e097d5fe92849ad3af2c2a313771ad2fbf1cadd4dc4afd552303b2bf3f85211 + category: main + optional: false +- name: webencodings + version: 0.5.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=2.6' + url: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_2.conda + hash: + md5: daf5160ff9cde3a468556965329085b9 + sha256: 2adf9bd5482802837bc8814cbe28d7b2a4cbd2e2c52e381329eaa283b3ed1944 + category: main + optional: false +- name: webencodings + version: 0.5.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=2.6' + url: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_2.conda + hash: + md5: daf5160ff9cde3a468556965329085b9 + sha256: 2adf9bd5482802837bc8814cbe28d7b2a4cbd2e2c52e381329eaa283b3ed1944 + category: main + optional: false +- name: websocket-client + version: 1.7.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.7.0-pyhd8ed1ab_0.conda + hash: + md5: 50ad31e07d706aae88b14a4ac9c73f23 + sha256: d9b537d5b7c5aa7a02a4ce4c6b755e458bd8083b67752a73c92d113ccec6c10f + category: main + optional: false +- name: websocket-client + version: 1.7.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.7.0-pyhd8ed1ab_0.conda + hash: + md5: 50ad31e07d706aae88b14a4ac9c73f23 + sha256: d9b537d5b7c5aa7a02a4ce4c6b755e458bd8083b67752a73c92d113ccec6c10f + category: main + optional: false +- name: werkzeug + version: 3.0.1 + manager: conda + platform: linux-64 + dependencies: + markupsafe: '>=2.1.1' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/werkzeug-3.0.1-pyhd8ed1ab_0.conda + hash: + md5: af8d825d93dbe6331ee6d61c69869ca0 + sha256: b7ac49549d370a411b1d6150d24243a15adcce07f1c61ec2ea1b536346e47aa0 + category: main + optional: false +- name: werkzeug + version: 3.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + markupsafe: '>=2.1.1' + url: https://conda.anaconda.org/conda-forge/noarch/werkzeug-3.0.1-pyhd8ed1ab_0.conda + hash: + md5: af8d825d93dbe6331ee6d61c69869ca0 + sha256: b7ac49549d370a411b1d6150d24243a15adcce07f1c61ec2ea1b536346e47aa0 + category: main + optional: false +- name: wheel + version: 0.42.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.42.0-pyhd8ed1ab_0.conda + hash: + md5: 1cdea58981c5cbc17b51973bcaddcea7 + sha256: 80be0ccc815ce22f80c141013302839b0ed938a2edb50b846cf48d8a8c1cfa01 + category: main + optional: false +- name: wheel + version: 0.42.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.42.0-pyhd8ed1ab_0.conda + hash: + md5: 1cdea58981c5cbc17b51973bcaddcea7 + sha256: 80be0ccc815ce22f80c141013302839b0ed938a2edb50b846cf48d8a8c1cfa01 + category: main + optional: false +- name: widgetsnbextension + version: 4.0.9 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.9-pyhd8ed1ab_0.conda + hash: + md5: 82617d07b2f5f5a96296d3c19684b37a + sha256: 35dd47b3c117cd759ac46da0b69064bebccd94862e795615ee65dbbe3e6cd86b + category: main + optional: false +- name: widgetsnbextension + version: 4.0.9 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.9-pyhd8ed1ab_0.conda + hash: + md5: 82617d07b2f5f5a96296d3c19684b37a + sha256: 35dd47b3c117cd759ac46da0b69064bebccd94862e795615ee65dbbe3e6cd86b + category: main + optional: false +- name: wrapt + version: 1.14.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/wrapt-1.14.1-py39hb9d737c_1.tar.bz2 + hash: + md5: f5906293b6eabeaaeafc90e427f9cbe5 + sha256: 16fa658554048c0eb37684685cf046ea3ef9e1f1fe03c92cbd8f726197ba60fe + category: main + optional: false +- name: wrapt + version: 1.14.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/wrapt-1.14.1-py39h02fc5c5_1.tar.bz2 + hash: + md5: ed6107ea31f4381e880cec32a5f986d9 + sha256: 83f5c4e8963137f6c0287846d118d9e3baac69cfa86b4734a4ea02f4e276422c + category: main + optional: false +- name: xerces-c + version: 3.2.4 + manager: conda + platform: linux-64 + dependencies: + icu: '>=73.2,<74.0a0' + libcurl: '>=8.2.1,<9.0a0' + libgcc-ng: '>=12' + libnsl: '>=2.0.0,<2.1.0a0' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/xerces-c-3.2.4-hac6953d_3.conda + hash: + md5: 297e6a75dc1b6a440cd341a85eab8a00 + sha256: faf1c8f0e625466efec442e987737057ca304f1fcf79055da4d9e93e49f14ffa + category: main + optional: false +- name: xorg-kbproto + version: 1.0.7 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-kbproto-1.0.7-h7f98852_1002.tar.bz2 + hash: + md5: 4b230e8381279d76131116660f5a241a + sha256: e90b0a6a5d41776f11add74aa030f789faf4efd3875c31964d6f9cfa63a10dd1 + category: main + optional: false +- name: xorg-libice + version: 1.1.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.1-hd590300_0.conda + hash: + md5: b462a33c0be1421532f28bfe8f4a7514 + sha256: 5aa9b3682285bb2bf1a8adc064cb63aff76ef9178769740d855abb42b0d24236 + category: main + optional: false +- name: xorg-libsm + version: 1.2.4 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libuuid: '>=2.38.1,<3.0a0' + xorg-libice: '>=1.1.1,<2.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.4-h7391055_0.conda + hash: + md5: 93ee23f12bc2e684548181256edd2cf6 + sha256: 089ad5f0453c604e18985480218a84b27009e9e6de9a0fa5f4a20b8778ede1f1 + category: main + optional: false +- name: xorg-libx11 + version: 1.8.7 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libxcb: '>=1.15,<1.16.0a0' + xorg-kbproto: '' + xorg-xextproto: '>=7.3.0,<8.0a0' + xorg-xproto: '' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.7-h8ee46fc_0.conda + hash: + md5: 49e482d882669206653b095f5206c05b + sha256: 7a02a7beac472ae2759498550b5fc5261bf5be7a9a2b4648a3f67818a7bfefcf + category: main + optional: false +- name: xorg-libxau + version: 1.0.11 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.11-hd590300_0.conda + hash: + md5: 2c80dc38fface310c9bd81b17037fee5 + sha256: 309751371d525ce50af7c87811b435c176915239fc9e132b99a25d5e1703f2d4 + category: main + optional: false +- name: xorg-libxau + version: 1.0.11 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.11-hb547adb_0.conda + hash: + md5: ca73dc4f01ea91e44e3ed76602c5ea61 + sha256: 02c313a1cada46912e5b9bdb355cfb4534bfe22143b4ea4ecc419690e793023b + category: main + optional: false +- name: xorg-libxdmcp + version: 1.1.3 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.3-h7f98852_0.tar.bz2 + hash: + md5: be93aabceefa2fac576e971aef407908 + sha256: 4df7c5ee11b8686d3453e7f3f4aa20ceef441262b49860733066c52cfd0e4a77 + category: main + optional: false +- name: xorg-libxdmcp + version: 1.1.3 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxdmcp-1.1.3-h27ca646_0.tar.bz2 + hash: + md5: 6738b13f7fadc18725965abdd4129c36 + sha256: d9a2fb4762779994718832f05a7d62ab2dcf6103a312235267628b5187ce88f7 + category: main + optional: false +- name: xorg-libxext + version: 1.3.4 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + xorg-libx11: '>=1.7.2,<2.0a0' + xorg-xextproto: '' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.4-h0b41bf4_2.conda + hash: + md5: 82b6df12252e6f32402b96dacc656fec + sha256: 73e5cfbdff41ef8a844441f884412aa5a585a0f0632ec901da035a03e1fe1249 + category: main + optional: false +- name: xorg-libxrender + version: 0.9.11 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + xorg-libx11: '>=1.8.6,<2.0a0' + xorg-renderproto: '' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.11-hd590300_0.conda + hash: + md5: ed67c36f215b310412b2af935bf3e530 + sha256: 26da4d1911473c965c32ce2b4ff7572349719eaacb88a066db8d968a4132c3f7 + category: main + optional: false +- name: xorg-renderproto + version: 0.11.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-renderproto-0.11.1-h7f98852_1002.tar.bz2 + hash: + md5: 06feff3d2634e3097ce2fe681474b534 + sha256: 38942930f233d1898594dd9edf4b0c0786f3dbc12065a0c308634c37fd936034 + category: main + optional: false +- name: xorg-xextproto + version: 7.3.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-xextproto-7.3.0-h0b41bf4_1003.conda + hash: + md5: bce9f945da8ad2ae9b1d7165a64d0f87 + sha256: b8dda3b560e8a7830fe23be1c58cc41f407b2e20ae2f3b6901eb5842ba62b743 + category: main + optional: false +- name: xorg-xproto + version: 7.0.31 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h7f98852_1007.tar.bz2 + hash: + md5: b4a4381d54784606820704f7b5f05a15 + sha256: f197bb742a17c78234c24605ad1fe2d88b1d25f332b75d73e5ba8cf8fbc2a10d + category: main + optional: false +- name: xxhash + version: 0.8.2 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.2-hd590300_0.conda + hash: + md5: f08fb5c89edfc4aadee1c81d4cfb1fa1 + sha256: 6fe74a8fd84ab0dc25e4dc3e0c22388dd8accb212897a208b14fe5d4fbb8fc2f + category: main + optional: false +- name: xxhash + version: 0.8.2 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/xxhash-0.8.2-hb547adb_0.conda + hash: + md5: 144cd3b88706507f332f5eb5fb83a33b + sha256: a70f59f7221ee72c45b39a6b36a33eb9c717ba01921cce1a3c361a4676979a2e + category: main + optional: false +- name: xyzservices + version: 2023.10.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2023.10.1-pyhd8ed1ab_0.conda + hash: + md5: 1e0d85c0e2fef9539218da185b285f54 + sha256: da655e2e0a742fddefeeaf2dd828b62a1820a3755d13341e1a555a10fcb9cf81 + category: main + optional: false +- name: xz + version: 5.2.6 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 + hash: + md5: 2161070d867d1b1204ea749c8eec4ef0 + sha256: 03a6d28ded42af8a347345f82f3eebdd6807a08526d47899a42d62d319609162 + category: main + optional: false +- name: xz + version: 5.2.6 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2 + hash: + md5: 39c6b54e94014701dd157f4f576ed211 + sha256: 59d78af0c3e071021cfe82dc40134c19dab8cdf804324b62940f5c8cd71803ec + category: main + optional: false +- name: yaml + version: 0.2.5 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=9.4.0' + url: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 + hash: + md5: 4cb3ad778ec2d5a7acbdf254eb1c42ae + sha256: a4e34c710eeb26945bdbdaba82d3d74f60a78f54a874ec10d373811a5d217535 + category: main + optional: false +- name: yaml + version: 0.2.5 + manager: conda + platform: osx-arm64 + dependencies: {} + url: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2 + hash: + md5: 4bb3f014845110883a3c5ee811fd84b4 + sha256: 93181a04ba8cfecfdfb162fc958436d868cc37db504c58078eab4c1a3e57fbb7 + category: main + optional: false +- name: yarl + version: 1.9.3 + manager: conda + platform: linux-64 + dependencies: + idna: '>=2.0' + libgcc-ng: '>=12' + multidict: '>=4.0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/linux-64/yarl-1.9.3-py39hd1e30aa_0.conda + hash: + md5: c8654dea9ff4b633fbdfddff7e321bb9 + sha256: 871782b22363b3fb449e2a29a3620045a1c40643e3726767f5b9cd4455ec36c7 + category: main + optional: false +- name: yarl + version: 1.9.3 + manager: conda + platform: osx-arm64 + dependencies: + idna: '>=2.0' + multidict: '>=4.0' + python: '>=3.9,<3.10.0a0' + python_abi: 3.9.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/yarl-1.9.3-py39h17cfd9d_0.conda + hash: + md5: b882e8dbbb5792b54bc8d9a44d742047 + sha256: 761a23146d980333d8ec0676ca9044f5f104804fc2ea753a0ba4ab1d3b6cda37 + category: main + optional: false +- name: zeromq + version: 4.3.5 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libsodium: '>=1.0.18,<1.0.19.0a0' + libstdcxx-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h59595ed_0.conda + hash: + md5: 8851084c192dbc56215ac4e3c9aa30fa + sha256: 53bf2a18224406e9806adb3b270a2c8a028aca0c89bd40114a85d6446f5c98d1 + category: main + optional: false +- name: zeromq + version: 4.3.5 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=10.9' + libcxx: '>=16.0.6' + libsodium: '>=1.0.18,<1.0.19.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h965bd2d_0.conda + hash: + md5: f460bbcb0ec8dc77989288fe8caa0f84 + sha256: 06abddc92d0bf83cd9faf25f26c98d7c2cc681cb50504011580b0584cf3cb1c5 + category: main + optional: false +- name: zict + version: 3.0.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda + hash: + md5: cf30c2c15b82aacb07f9c09e28ff2275 + sha256: 3d65c081514569ab3642ba7e6c2a6b4615778b596db6b1c82ee30a2d912539e5 + category: main + optional: false +- name: zict + version: 3.0.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda + hash: + md5: cf30c2c15b82aacb07f9c09e28ff2275 + sha256: 3d65c081514569ab3642ba7e6c2a6b4615778b596db6b1c82ee30a2d912539e5 + category: main + optional: false +- name: zipp + version: 3.17.0 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda + hash: + md5: 2e4d6bc0b14e10f895fc6791a7d9b26a + sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26 + category: main + optional: false +- name: zipp + version: 3.17.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda + hash: + md5: 2e4d6bc0b14e10f895fc6791a7d9b26a + sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26 + category: main + optional: false +- name: zlib + version: 1.2.13 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libzlib: 1.2.13 + url: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-hd590300_5.conda + hash: + md5: 68c34ec6149623be41a1933ab996a209 + sha256: 9887a04d7e7cb14bd2b52fa01858f05a6d7f002c890f618d9fcd864adbfecb1b + category: main + optional: false +- name: zlib + version: 1.2.13 + manager: conda + platform: osx-arm64 + dependencies: + libzlib: 1.2.13 + url: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.2.13-h53f4e23_5.conda + hash: + md5: a08383f223b10b71492d27566fafbf6c + sha256: de0ee1e24aa6867058d3b852a15c8d7f49f262f5828772700c647186d4a96bbe + category: main + optional: false +- name: zstd + version: 1.5.5 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.5-hfc55251_0.conda + hash: + md5: 04b88013080254850d6c01ed54810589 + sha256: 607cbeb1a533be98ba96cf5cdf0ddbb101c78019f1fda063261871dad6248609 + category: main + optional: false +- name: zstd + version: 1.5.5 + manager: conda + platform: osx-arm64 + dependencies: + libzlib: '>=1.2.13,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.5-h4f39d0f_0.conda + hash: + md5: 5b212cfb7f9d71d603ad891879dc7933 + sha256: 7e1fe6057628bbb56849a6741455bbb88705bae6d6646257e57904ac5ee5a481 + category: main + optional: false +- name: annotated-types + version: 0.6.0 + manager: pip + platform: linux-64 + dependencies: {} + url: https://files.pythonhosted.org/packages/28/78/d31230046e58c207284c6b2c4e8d96e6d3cb4e52354721b944d3e1ee4aa5/annotated_types-0.6.0-py3-none-any.whl + hash: + sha256: 0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 + category: main + optional: false +- name: annotated-types + version: 0.6.0 + manager: pip + platform: osx-arm64 + dependencies: {} + url: https://files.pythonhosted.org/packages/28/78/d31230046e58c207284c6b2c4e8d96e6d3cb4e52354721b944d3e1ee4aa5/annotated_types-0.6.0-py3-none-any.whl + hash: + sha256: 0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 + category: main + optional: false +- name: dacite + version: 1.8.1 + manager: pip + platform: linux-64 + dependencies: {} + url: https://files.pythonhosted.org/packages/21/0f/cf0943f4f55f0fbc7c6bd60caf1343061dff818b02af5a0d444e473bb78d/dacite-1.8.1-py3-none-any.whl + hash: + sha256: cc31ad6fdea1f49962ea42db9421772afe01ac5442380d9a99fcf3d188c61afe + category: main + optional: false +- name: dacite + version: 1.8.1 + manager: pip + platform: osx-arm64 + dependencies: {} + url: https://files.pythonhosted.org/packages/21/0f/cf0943f4f55f0fbc7c6bd60caf1343061dff818b02af5a0d444e473bb78d/dacite-1.8.1-py3-none-any.whl + hash: + sha256: cc31ad6fdea1f49962ea42db9421772afe01ac5442380d9a99fcf3d188c61afe + category: main + optional: false +- name: dolt-integrations + version: 0.1.5 + manager: pip + platform: linux-64 + dependencies: + pandas: '>=0.25.2' + dataclasses-json: '>=0.5.2' + doltcli: '>=0.1.6,<0.2.0' + url: https://files.pythonhosted.org/packages/a6/24/318bd96f965b8b8c37d38a1b2268029e500718d19913fdc59e569eb14161/dolt_integrations-0.1.5-py3-none-any.whl + hash: + sha256: d90eb2eb4cae3dbc50f544f37e3a71bf50fdda8428109cfc15056fe94febc1b4 + category: main + optional: false +- name: dolt-integrations + version: 0.1.5 + manager: pip + platform: osx-arm64 + dependencies: + pandas: '>=0.25.2' + dataclasses-json: '>=0.5.2' + doltcli: '>=0.1.6,<0.2.0' + url: https://files.pythonhosted.org/packages/a6/24/318bd96f965b8b8c37d38a1b2268029e500718d19913fdc59e569eb14161/dolt_integrations-0.1.5-py3-none-any.whl + hash: + sha256: d90eb2eb4cae3dbc50f544f37e3a71bf50fdda8428109cfc15056fe94febc1b4 + category: main + optional: false +- name: doltcli + version: 0.1.18 + manager: pip + platform: linux-64 + dependencies: + typed-ast: '>1.4.3' + url: https://files.pythonhosted.org/packages/19/d0/3a3119ca82af8d27c06d2f1fe826f4ae8be2a3bd3e5a4c7a59852e962059/doltcli-0.1.18-py3-none-any.whl + hash: + sha256: 9d8a8454ef2337d388e40de2fc915fbc6d616e4ac494926488d0d4da9ce1747a + category: main + optional: false +- name: doltcli + version: 0.1.18 + manager: pip + platform: osx-arm64 + dependencies: + typed-ast: '>1.4.3' + url: https://files.pythonhosted.org/packages/19/d0/3a3119ca82af8d27c06d2f1fe826f4ae8be2a3bd3e5a4c7a59852e962059/doltcli-0.1.18-py3-none-any.whl + hash: + sha256: 9d8a8454ef2337d388e40de2fc915fbc6d616e4ac494926488d0d4da9ce1747a + category: main + optional: false +- name: duckdb + version: 0.9.2 + manager: pip + platform: linux-64 + dependencies: {} + url: https://files.pythonhosted.org/packages/1d/95/ec3eb63bbb3569206a55596c4130508921ec496b1ba1f202743054cf96e0/duckdb-0.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + hash: + sha256: a5cfb93e73911696a98b9479299d19cfbc21dd05bb7ab11a923a903f86b4d06e + category: main + optional: false +- name: duckdb + version: 0.9.2 + manager: pip + platform: osx-arm64 + dependencies: {} + url: https://files.pythonhosted.org/packages/54/75/701914dae093eeb431e39288c2d39d21f2f2430ed9010977a88890765d45/duckdb-0.9.2-cp39-cp39-macosx_11_0_arm64.whl + hash: + sha256: 4ce262d74a52500d10888110dfd6715989926ec936918c232dcbaddb78fc55b4 + category: main + optional: false +- name: flytekitplugins-deck-standard + version: 1.10.2 + manager: pip + platform: linux-64 + dependencies: + flytekit: '>=1.3.0b2,<2.0.0' + markdown: '*' + plotly: '*' + ydata-profiling: '*' + ipywidgets: '*' + url: https://files.pythonhosted.org/packages/c4/13/1f7c371031967e541012eb017b95dd266ccd919abe7ed6996a96870e39ea/flytekitplugins_deck_standard-1.10.2-py3-none-any.whl + hash: + sha256: bb71de7d462b2ca51d42812fb61a2ca3e42ad19866fe973bef1ffa0ce147965c + category: main + optional: false +- name: flytekitplugins-deck-standard + version: 1.10.2 + manager: pip + platform: osx-arm64 + dependencies: + flytekit: '>=1.3.0b2,<2.0.0' + markdown: '*' + plotly: '*' + ydata-profiling: '*' + ipywidgets: '*' + url: https://files.pythonhosted.org/packages/c4/13/1f7c371031967e541012eb017b95dd266ccd919abe7ed6996a96870e39ea/flytekitplugins_deck_standard-1.10.2-py3-none-any.whl + hash: + sha256: bb71de7d462b2ca51d42812fb61a2ca3e42ad19866fe973bef1ffa0ce147965c + category: main + optional: false +- name: flytekitplugins-kfpytorch + version: 1.10.2 + manager: pip + platform: linux-64 + dependencies: + cloudpickle: '*' + flyteidl: '>=1.5.1' + flytekit: '>=1.6.1' + url: https://files.pythonhosted.org/packages/b0/31/64f935cfc7d2784101045fdc9151ab38036057afb8d102793e4f8a76e22d/flytekitplugins_kfpytorch-1.10.2-py3-none-any.whl + hash: + sha256: baac1698148a63f72478b063ee93ad81346626407f302ea0f6f44b1083e2e723 + category: main + optional: false +- name: flytekitplugins-kfpytorch + version: 1.10.2 + manager: pip + platform: osx-arm64 + dependencies: + cloudpickle: '*' + flyteidl: '>=1.5.1' + flytekit: '>=1.6.1' + url: https://files.pythonhosted.org/packages/b0/31/64f935cfc7d2784101045fdc9151ab38036057afb8d102793e4f8a76e22d/flytekitplugins_kfpytorch-1.10.2-py3-none-any.whl + hash: + sha256: baac1698148a63f72478b063ee93ad81346626407f302ea0f6f44b1083e2e723 + category: main + optional: false +- name: flytekitplugins-sqlalchemy + version: 1.10.2 + manager: pip + platform: linux-64 + dependencies: + flytekit: '>=1.3.0b2,<2.0.0' + sqlalchemy: '>=1.4.7' + url: https://files.pythonhosted.org/packages/99/c3/82bb331973c1ee7fd374e314f209d4bffb63d896a1f345da145cac24a91a/flytekitplugins_sqlalchemy-1.10.2-py3-none-any.whl + hash: + sha256: 9e19b16edfc7468c94e1e69801a465abe89412e5c46d50a19e283ab717afca3f + category: main + optional: false +- name: flytekitplugins-sqlalchemy + version: 1.10.2 + manager: pip + platform: osx-arm64 + dependencies: + flytekit: '>=1.3.0b2,<2.0.0' + sqlalchemy: '>=1.4.7' + url: https://files.pythonhosted.org/packages/99/c3/82bb331973c1ee7fd374e314f209d4bffb63d896a1f345da145cac24a91a/flytekitplugins_sqlalchemy-1.10.2-py3-none-any.whl + hash: + sha256: 9e19b16edfc7468c94e1e69801a465abe89412e5c46d50a19e283ab717afca3f + category: main + optional: false +- name: google-auth-oauthlib + version: 0.6.0 + manager: pip + platform: osx-arm64 + dependencies: + google-auth: '>=1.0.0' + requests-oauthlib: '>=0.7.0' + url: https://files.pythonhosted.org/packages/4d/d1/79277a5c507df72cc22ee2c3949ae384c4af8110bc0b472f0c49fcdcba3b/google_auth_oauthlib-0.6.0-py2.py3-none-any.whl + hash: + sha256: 69112d0890c075e6ab03950cd9b8e1b953d6e89ba51de5f393e939fb3bc68284 + category: main + optional: false +- name: google-cloud + version: 0.34.0 + manager: pip + platform: linux-64 + dependencies: {} + url: https://files.pythonhosted.org/packages/ba/b1/7c54d1950e7808df06642274e677dbcedba57f75307adf2e5ad8d39e5e0e/google_cloud-0.34.0-py2.py3-none-any.whl + hash: + sha256: fb1ab7b0548fe44b3d538041f0a374505b7f990d448a935ea36649c5ccab5acf + category: main + optional: false +- name: google-cloud + version: 0.34.0 + manager: pip + platform: osx-arm64 + dependencies: {} + url: https://files.pythonhosted.org/packages/ba/b1/7c54d1950e7808df06642274e677dbcedba57f75307adf2e5ad8d39e5e0e/google_cloud-0.34.0-py2.py3-none-any.whl + hash: + sha256: fb1ab7b0548fe44b3d538041f0a374505b7f990d448a935ea36649c5ccab5acf + category: main + optional: false +- name: htmlmin + version: 0.1.12 + manager: pip + platform: linux-64 + dependencies: {} + url: https://files.pythonhosted.org/packages/b3/e7/fcd59e12169de19f0131ff2812077f964c6b960e7c09804d30a7bf2ab461/htmlmin-0.1.12.tar.gz + hash: + sha256: 50c1ef4630374a5d723900096a961cff426dff46b48f34d194a81bbe14eca178 + category: main + optional: false +- name: htmlmin + version: 0.1.12 + manager: pip + platform: osx-arm64 + dependencies: {} + url: https://files.pythonhosted.org/packages/b3/e7/fcd59e12169de19f0131ff2812077f964c6b960e7c09804d30a7bf2ab461/htmlmin-0.1.12.tar.gz + hash: + sha256: 50c1ef4630374a5d723900096a961cff426dff46b48f34d194a81bbe14eca178 + category: main + optional: false +- name: imagehash + version: 4.3.1 + manager: pip + platform: linux-64 + dependencies: + pywavelets: '*' + numpy: '*' + pillow: '*' + scipy: '*' + url: https://files.pythonhosted.org/packages/2d/b4/19a746a986c6e38595fa5947c028b1b8e287773dcad766e648897ad2a4cf/ImageHash-4.3.1-py2.py3-none-any.whl + hash: + sha256: 5ad9a5cde14fe255745a8245677293ac0d67f09c330986a351f34b614ba62fb5 + category: main + optional: false +- name: imagehash + version: 4.3.1 + manager: pip + platform: osx-arm64 + dependencies: + pywavelets: '*' + numpy: '*' + pillow: '*' + scipy: '*' + url: https://files.pythonhosted.org/packages/2d/b4/19a746a986c6e38595fa5947c028b1b8e287773dcad766e648897ad2a4cf/ImageHash-4.3.1-py2.py3-none-any.whl + hash: + sha256: 5ad9a5cde14fe255745a8245677293ac0d67f09c330986a351f34b614ba62fb5 + category: main + optional: false +- name: jaraco.classes + version: 3.3.0 + manager: pip + platform: linux-64 + dependencies: + more-itertools: '*' + url: https://files.pythonhosted.org/packages/c7/6b/1bc8fa93ea85146e08f0e0883bc579b7c7328364ed7df90b1628dcb36e10/jaraco.classes-3.3.0-py3-none-any.whl + hash: + sha256: 10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb + category: main + optional: false +- name: jaraco.classes + version: 3.3.0 + manager: pip + platform: osx-arm64 + dependencies: + more-itertools: '*' + url: https://files.pythonhosted.org/packages/c7/6b/1bc8fa93ea85146e08f0e0883bc579b7c7328364ed7df90b1628dcb36e10/jaraco.classes-3.3.0-py3-none-any.whl + hash: + sha256: 10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb + category: main + optional: false +- name: llvmlite + version: 0.41.1 + manager: pip + platform: linux-64 + dependencies: {} + url: https://files.pythonhosted.org/packages/be/a6/55020df7f04666bceb3ccc5dc0cb0812d68d5fdec883ff015a9110928829/llvmlite-0.41.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + hash: + sha256: 24091a6b31242bcdd56ae2dbea40007f462260bc9bdf947953acc39dffd54f8f + category: main + optional: false +- name: llvmlite + version: 0.41.1 + manager: pip + platform: osx-arm64 + dependencies: {} + url: https://files.pythonhosted.org/packages/8b/66/b3edcd1b2631af2daaf7a09520c5ff863e459eb17dd28f7d4cac63f3532c/llvmlite-0.41.1-cp39-cp39-macosx_11_0_arm64.whl + hash: + sha256: bf14aa0eb22b58c231243dccf7e7f42f7beec48970f2549b3a6acc737d1a4ba4 + category: main + optional: false +- name: numba + version: 0.58.1 + manager: pip + platform: linux-64 + dependencies: + llvmlite: '>=0.41.0dev0,<0.42' + numpy: '>=1.22,<1.27' + url: https://files.pythonhosted.org/packages/8b/4b/58bdecd06266c5395157727d7191d83c82d190665bdf3d65fdd67a6dbaa5/numba-0.58.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + hash: + sha256: 45698b995914003f890ad839cfc909eeb9c74921849c712a05405d1a79c50f68 + category: main + optional: false +- name: numba + version: 0.58.1 + manager: pip + platform: osx-arm64 + dependencies: + llvmlite: '>=0.41.0dev0,<0.42' + numpy: '>=1.22,<1.27' + url: https://files.pythonhosted.org/packages/eb/61/db566ad7cd3f7e9191ec744f25cf6455e8d91732ad70be8fcdd203a48dab/numba-0.58.1-cp39-cp39-macosx_11_0_arm64.whl + hash: + sha256: 9e9356e943617f5e35a74bf56ff6e7cc83e6b1865d5e13cee535d79bf2cae954 + category: main + optional: false +- name: patsy + version: 0.5.4 + manager: pip + platform: linux-64 + dependencies: + six: '*' + numpy: '>=1.4' + url: https://files.pythonhosted.org/packages/29/ab/373449d6f741732f94e2d15d116a90f050b2857cb727b26d2f7bead50815/patsy-0.5.4-py2.py3-none-any.whl + hash: + sha256: 0486413077a527db51ddea8fa94a5234d0feb17a4f4dc01b59b6086c58a70f80 + category: main + optional: false +- name: patsy + version: 0.5.4 + manager: pip + platform: osx-arm64 + dependencies: + six: '*' + numpy: '>=1.4' + url: https://files.pythonhosted.org/packages/29/ab/373449d6f741732f94e2d15d116a90f050b2857cb727b26d2f7bead50815/patsy-0.5.4-py2.py3-none-any.whl + hash: + sha256: 0486413077a527db51ddea8fa94a5234d0feb17a4f4dc01b59b6086c58a70f80 + category: main + optional: false +- name: phik + version: 0.12.3 + manager: pip + platform: linux-64 + dependencies: + numpy: '>=1.18.0' + scipy: '>=1.5.2' + pandas: '>=0.25.1' + matplotlib: '>=2.2.3' + joblib: '>=0.14.1' + url: https://files.pythonhosted.org/packages/3a/76/c9b729aaf03cc850bd4b0e1a55220ea36dc7b6cfbefd7cfa884e708f5228/phik-0.12.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + hash: + sha256: cfed89c9a1bb88d80df8259bb30aa650244c877aaaca218025d92324074716b9 + category: main + optional: false +- name: phik + version: 0.12.3 + manager: pip + platform: osx-arm64 + dependencies: + numpy: '>=1.18.0' + scipy: '>=1.5.2' + pandas: '>=0.25.1' + matplotlib: '>=2.2.3' + joblib: '>=0.14.1' + url: https://files.pythonhosted.org/packages/11/c0/ae6bed243d3e7194a4a2b31e32682ca852cff7b564b38b4e5493cc4f4e49/phik-0.12.3-cp39-cp39-macosx_11_0_arm64.whl + hash: + sha256: baac8ace316b801cdb38c84cd0e7e35e60d17d50032c34af9879b0cd91c20861 + category: main + optional: false +- name: pydantic + version: 2.5.2 + manager: pip + platform: linux-64 + dependencies: + annotated-types: '>=0.4.0' + pydantic-core: 2.14.5 + typing-extensions: '>=4.6.1' + url: https://files.pythonhosted.org/packages/0a/2b/64066de1c4cf3d4ed623beeb3bbf3f8d0cc26661f1e7d180ec5eb66b75a5/pydantic-2.5.2-py3-none-any.whl + hash: + sha256: 80c50fb8e3dcecfddae1adbcc00ec5822918490c99ab31f6cf6140ca1c1429f0 + category: main + optional: false +- name: pydantic + version: 2.5.2 + manager: pip + platform: osx-arm64 + dependencies: + annotated-types: '>=0.4.0' + pydantic-core: 2.14.5 + typing-extensions: '>=4.6.1' + url: https://files.pythonhosted.org/packages/0a/2b/64066de1c4cf3d4ed623beeb3bbf3f8d0cc26661f1e7d180ec5eb66b75a5/pydantic-2.5.2-py3-none-any.whl + hash: + sha256: 80c50fb8e3dcecfddae1adbcc00ec5822918490c99ab31f6cf6140ca1c1429f0 + category: main + optional: false +- name: pydantic-core + version: 2.14.5 + manager: pip + platform: linux-64 + dependencies: + typing-extensions: '>=4.6.0,<4.7.0 || >4.7.0' + url: https://files.pythonhosted.org/packages/2a/b7/f85e5fd4504fae0df3eadd4bf9e0c495ecbdb804dc9be65653119454571e/pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + hash: + sha256: c339dabd8ee15f8259ee0f202679b6324926e5bc9e9a40bf981ce77c038553db + category: main + optional: false +- name: pydantic-core + version: 2.14.5 + manager: pip + platform: osx-arm64 + dependencies: + typing-extensions: '>=4.6.0,<4.7.0 || >4.7.0' + url: https://files.pythonhosted.org/packages/bf/d2/4820db26970effb5d6fdee68f578585448b2eb6dd7344ab55b20958a0874/pydantic_core-2.14.5-cp39-cp39-macosx_11_0_arm64.whl + hash: + sha256: abf058be9517dc877227ec3223f0300034bd0e9f53aebd63cf4456c8cb1e0863 + category: main + optional: false +- name: pywavelets + version: 1.5.0 + manager: pip + platform: linux-64 + dependencies: + numpy: '>=1.22.4,<2.0' + url: https://files.pythonhosted.org/packages/a7/58/1724d6362becfa71eded2dffe145e795786b13c3a66f6523f3aff1b3f3cf/pywavelets-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + hash: + sha256: 49aa6abf9ac941f47f7ea26a3c7dd5c8bfcf0e903dc5ec68ed105b52bfccd4e2 + category: main + optional: false +- name: pywavelets + version: 1.5.0 + manager: pip + platform: osx-arm64 + dependencies: + numpy: '>=1.22.4,<2.0' + url: https://files.pythonhosted.org/packages/46/76/83c185662c782b71807fe84fa92f74d0f930661457aaf180f7163b4d5e59/pywavelets-1.5.0-cp39-cp39-macosx_11_0_arm64.whl + hash: + sha256: 00d5c37775a2baa4e5e6e9df3f93e6fc700a76bd50acd3b234bb13467cc54b6b + category: main + optional: false +- name: ray + version: 2.6.3 + manager: pip + platform: linux-64 + dependencies: + click: '>=7.0' + filelock: '*' + jsonschema: '*' + msgpack: '>=1.0.0,<2.0.0' + packaging: '*' + protobuf: '>=3.15.3,<3.19.5 || >3.19.5' + pyyaml: '*' + aiosignal: '*' + frozenlist: '*' + requests: '*' + grpcio: '>=1.32.0' + numpy: '>=1.19.3' + url: https://files.pythonhosted.org/packages/3e/da/9bf3ac45a2e26f8000ea7d48caa308681a742d69d6cc0fb18be82f26692c/ray-2.6.3-cp39-cp39-manylinux2014_x86_64.whl + hash: + sha256: 18d033cc468e5171d9995476c33f99a5b79f091c34265c7e9f3d8b1c9042437e + category: main + optional: false +- name: ray + version: 2.6.3 + manager: pip + platform: osx-arm64 + dependencies: + click: '>=7.0' + filelock: '*' + jsonschema: '*' + msgpack: '>=1.0.0,<2.0.0' + packaging: '*' + protobuf: '>=3.15.3,<3.19.5 || >3.19.5' + pyyaml: '*' + aiosignal: '*' + frozenlist: '*' + requests: '*' + grpcio: '>=1.32.0' + numpy: '>=1.19.3' + url: https://files.pythonhosted.org/packages/c7/c2/a0278ba2c7d0fe6ac0cfac8be922abfd0d743c112064a374aaafa8c7d5d5/ray-2.6.3-cp39-cp39-macosx_11_0_arm64.whl + hash: + sha256: a4ef2f52319286720be7f3bfe6043e9fd0b8cb7826cb2ffc90c23c1c42427464 + category: main + optional: false +- name: seaborn + version: 0.12.2 + manager: pip + platform: linux-64 + dependencies: + numpy: '>=1.17,<1.24.0 || >1.24.0' + pandas: '>=0.25' + matplotlib: '>=3.1,<3.6.1 || >3.6.1' + url: https://files.pythonhosted.org/packages/8f/2e/17bbb83fbf102687bb2aa3d808add39da820a7698159302a1a69bb82e01c/seaborn-0.12.2-py3-none-any.whl + hash: + sha256: ebf15355a4dba46037dfd65b7350f014ceb1f13c05e814eda2c9f5fd731afc08 + category: main + optional: false +- name: seaborn + version: 0.12.2 + manager: pip + platform: osx-arm64 + dependencies: + numpy: '>=1.17,<1.24.0 || >1.24.0' + pandas: '>=0.25' + matplotlib: '>=3.1,<3.6.1 || >3.6.1' + url: https://files.pythonhosted.org/packages/8f/2e/17bbb83fbf102687bb2aa3d808add39da820a7698159302a1a69bb82e01c/seaborn-0.12.2-py3-none-any.whl + hash: + sha256: ebf15355a4dba46037dfd65b7350f014ceb1f13c05e814eda2c9f5fd731afc08 + category: main + optional: false +- name: sphinx-code-include + version: 1.1.1 + manager: pip + platform: linux-64 + dependencies: + beautifulsoup4: '>=4.8' + six: '>=1.12' + sphinx: '>=1.3' + url: https://files.pythonhosted.org/packages/89/bf/95e6eb1b9a5cf502684006c9ac8a11f7d543a95a45856dcaf8f7bf9b31f1/sphinx_code_include-1.1.1-py2.py3-none-any.whl + hash: + sha256: 8c7d680fabb9fe45a74d036c967a61ef574fe1bd49d1539a74f52b9abbe50207 + category: main + optional: false +- name: sphinx-code-include + version: 1.1.1 + manager: pip + platform: osx-arm64 + dependencies: + beautifulsoup4: '>=4.8' + six: '>=1.12' + sphinx: '>=1.3' + url: https://files.pythonhosted.org/packages/89/bf/95e6eb1b9a5cf502684006c9ac8a11f7d543a95a45856dcaf8f7bf9b31f1/sphinx_code_include-1.1.1-py2.py3-none-any.whl + hash: + sha256: 8c7d680fabb9fe45a74d036c967a61ef574fe1bd49d1539a74f52b9abbe50207 + category: main + optional: false +- name: sphinx-markdown-tables + version: 0.0.17 + manager: pip + platform: linux-64 + dependencies: + markdown: '>=3.4' + url: https://files.pythonhosted.org/packages/93/8d/8785a36892992582ef8d87c69ab90e26124ab1059c501d93ebecd99d2323/sphinx_markdown_tables-0.0.17-py3-none-any.whl + hash: + sha256: 2bd0c30779653e4dd120300cbd9ca412c480738cc2241f6dea477a883f299e04 + category: main + optional: false +- name: sphinx-markdown-tables + version: 0.0.17 + manager: pip + platform: osx-arm64 + dependencies: + markdown: '>=3.4' + url: https://files.pythonhosted.org/packages/93/8d/8785a36892992582ef8d87c69ab90e26124ab1059c501d93ebecd99d2323/sphinx_markdown_tables-0.0.17-py3-none-any.whl + hash: + sha256: 2bd0c30779653e4dd120300cbd9ca412c480738cc2241f6dea477a883f299e04 + category: main + optional: false +- name: sphinxcontrib-video + version: 0.2.0 + manager: pip + platform: linux-64 + dependencies: + sphinx: '*' + url: https://files.pythonhosted.org/packages/76/7e/d346546cfc532a52c3a3c961100ea023e77a0c1c51b1ab5a500421a285c6/sphinxcontrib_video-0.2.0-py3-none-any.whl + hash: + sha256: 8973278316c02547efd0910bfd69205385462c423885cf03edc28b1c66f3b23c + category: main + optional: false +- name: sphinxcontrib-video + version: 0.2.0 + manager: pip + platform: osx-arm64 + dependencies: + sphinx: '*' + url: https://files.pythonhosted.org/packages/76/7e/d346546cfc532a52c3a3c961100ea023e77a0c1c51b1ab5a500421a285c6/sphinxcontrib_video-0.2.0-py3-none-any.whl + hash: + sha256: 8973278316c02547efd0910bfd69205385462c423885cf03edc28b1c66f3b23c + category: main + optional: false +- name: sphinxext-remoteliteralinclude + version: 0.4.0 + manager: pip + platform: linux-64 + dependencies: + six: '*' + url: https://files.pythonhosted.org/packages/13/0d/7e5009f48c33d5fd533dda80b42c4a79fce8dfdd1b617d0a9df9a9836145/sphinxext_remoteliteralinclude-0.4.0-py3-none-any.whl + hash: + sha256: e91378f07f378e6ca435246e07334c19a8c16b9baf6e180fc3e428a359846ea2 + category: main + optional: false +- name: sphinxext-remoteliteralinclude + version: 0.4.0 + manager: pip + platform: osx-arm64 + dependencies: + six: '*' + url: https://files.pythonhosted.org/packages/13/0d/7e5009f48c33d5fd533dda80b42c4a79fce8dfdd1b617d0a9df9a9836145/sphinxext_remoteliteralinclude-0.4.0-py3-none-any.whl + hash: + sha256: e91378f07f378e6ca435246e07334c19a8c16b9baf6e180fc3e428a359846ea2 + category: main + optional: false +- name: statsmodels + version: 0.14.0 + manager: pip + platform: linux-64 + dependencies: + numpy: '>=1.18' + scipy: '>=1.4,<1.9.2 || >1.9.2' + pandas: '>=1.0' + patsy: '>=0.5.2' + packaging: '>=21.3' + url: https://files.pythonhosted.org/packages/77/e8/80a06b41754b82f1cf08fc7271e95c9b345cbe3d65ab71224f7f2489f338/statsmodels-0.14.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + hash: + sha256: 68b1c768dd94cc5ba8398121a632b673c625491aa7ed627b82cb4c880a25563f + category: main + optional: false +- name: statsmodels + version: 0.14.0 + manager: pip + platform: osx-arm64 + dependencies: + numpy: '>=1.18' + scipy: '>=1.4,<1.9.2 || >1.9.2' + pandas: '>=1.0' + patsy: '>=0.5.2' + packaging: '>=21.3' + url: https://files.pythonhosted.org/packages/cf/35/27e12575cafd5702189f46fe8777935f180656c168f9cdfa7178fd45cb34/statsmodels-0.14.0-cp39-cp39-macosx_11_0_arm64.whl + hash: + sha256: 3b0a135f3bfdeec987e36e3b3b4c53e0bb87a8d91464d2fcc4d169d176f46fdb + category: main + optional: false +- name: tangled-up-in-unicode + version: 0.2.0 + manager: pip + platform: linux-64 + dependencies: {} + url: https://files.pythonhosted.org/packages/dd/60/3651960b74aead282ec1ad819e70bdccf3ee73322d13d4339a6e3f5b7ed3/tangled_up_in_unicode-0.2.0-py3-none-any.whl + hash: + sha256: 154be12605b1687a17133aa741ae951cf9ee531c48a0c19f98d83ec5cb3cc7be + category: main + optional: false +- name: tangled-up-in-unicode + version: 0.2.0 + manager: pip + platform: osx-arm64 + dependencies: {} + url: https://files.pythonhosted.org/packages/dd/60/3651960b74aead282ec1ad819e70bdccf3ee73322d13d4339a6e3f5b7ed3/tangled_up_in_unicode-0.2.0-py3-none-any.whl + hash: + sha256: 154be12605b1687a17133aa741ae951cf9ee531c48a0c19f98d83ec5cb3cc7be + category: main + optional: false +- name: typed-ast + version: 1.5.5 + manager: pip + platform: linux-64 + dependencies: {} + url: https://files.pythonhosted.org/packages/ea/f4/262512d14f777ea3666a089e2675a9b1500a85b8329a36de85d63433fb0e/typed_ast-1.5.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + hash: + sha256: f0aefdd66f1784c58f65b502b6cf8b121544680456d1cebbd300c2c813899274 + category: main + optional: false +- name: typed-ast + version: 1.5.5 + manager: pip + platform: osx-arm64 + dependencies: {} + url: https://files.pythonhosted.org/packages/71/30/09d27e13824495547bcc665bd07afc593b22b9484f143b27565eae4ccaac/typed_ast-1.5.5-cp39-cp39-macosx_11_0_arm64.whl + hash: + sha256: 622e4a006472b05cf6ef7f9f2636edc51bda670b7bbffa18d26b255269d3d814 + category: main + optional: false +- name: types-requests + version: 2.30.0.0 + manager: pip + platform: linux-64 + dependencies: + types-urllib3: '*' + url: https://files.pythonhosted.org/packages/fa/c7/024171d587afe75934a6f779922d24fcc6dd468e947c74598eb17840e229/types_requests-2.30.0.0-py3-none-any.whl + hash: + sha256: c6cf08e120ca9f0dc4fa4e32c3f953c3fba222bcc1db6b97695bce8da1ba9864 + category: main + optional: false +- name: types-requests + version: 2.30.0.0 + manager: pip + platform: osx-arm64 + dependencies: + types-urllib3: '*' + url: https://files.pythonhosted.org/packages/fa/c7/024171d587afe75934a6f779922d24fcc6dd468e947c74598eb17840e229/types_requests-2.30.0.0-py3-none-any.whl + hash: + sha256: c6cf08e120ca9f0dc4fa4e32c3f953c3fba222bcc1db6b97695bce8da1ba9864 + category: main + optional: false +- name: types-urllib3 + version: 1.26.25.14 + manager: pip + platform: linux-64 + dependencies: {} + url: https://files.pythonhosted.org/packages/11/7b/3fc711b2efea5e85a7a0bbfe269ea944aa767bbba5ec52f9ee45d362ccf3/types_urllib3-1.26.25.14-py3-none-any.whl + hash: + sha256: 9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e + category: main + optional: false +- name: types-urllib3 + version: 1.26.25.14 + manager: pip + platform: osx-arm64 + dependencies: {} + url: https://files.pythonhosted.org/packages/11/7b/3fc711b2efea5e85a7a0bbfe269ea944aa767bbba5ec52f9ee45d362ccf3/types_urllib3-1.26.25.14-py3-none-any.whl + hash: + sha256: 9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e + category: main + optional: false +- name: visions + version: 0.7.5 + manager: pip + platform: linux-64 + dependencies: + numpy: '*' + pandas: '>=0.25.3' + attrs: '>=19.3.0' + networkx: '>=2.4' + tangled-up-in-unicode: '>=0.0.4' + multimethod: '>=1.4' + imagehash: '*' + pillow: '*' + url: https://files.pythonhosted.org/packages/62/fa/6a8539c83d2ccbd08d5f0c843b1784af9ff514e77f4c9d5d6800fdd340f6/visions-0.7.5-py3-none-any.whl + hash: + sha256: 1e57219715255282a909cfb93d25d6e453535aa0c26640a0d6f03e40be6263d7 + category: main + optional: false +- name: visions + version: 0.7.5 + manager: pip + platform: osx-arm64 + dependencies: + numpy: '*' + pandas: '>=0.25.3' + attrs: '>=19.3.0' + networkx: '>=2.4' + tangled-up-in-unicode: '>=0.0.4' + multimethod: '>=1.4' + imagehash: '*' + pillow: '*' + url: https://files.pythonhosted.org/packages/62/fa/6a8539c83d2ccbd08d5f0c843b1784af9ff514e77f4c9d5d6800fdd340f6/visions-0.7.5-py3-none-any.whl + hash: + sha256: 1e57219715255282a909cfb93d25d6e453535aa0c26640a0d6f03e40be6263d7 + category: main + optional: false +- name: whylabs-client + version: 0.5.9 + manager: pip + platform: linux-64 + dependencies: + urllib3: '>=1.25.3' + python-dateutil: '*' + url: https://files.pythonhosted.org/packages/b1/48/a7a8d3d55a4751497c68f2fd1c3da1bfb1145a47870ae571295de8fa329d/whylabs_client-0.5.9-py3-none-any.whl + hash: + sha256: 540f85f490b00abcd29237a6bf39967fea85cac452f1262a762a6667bf0a5f7a + category: main + optional: false +- name: whylabs-client + version: 0.5.9 + manager: pip + platform: osx-arm64 + dependencies: + urllib3: '>=1.25.3' + python-dateutil: '*' + url: https://files.pythonhosted.org/packages/b1/48/a7a8d3d55a4751497c68f2fd1c3da1bfb1145a47870ae571295de8fa329d/whylabs_client-0.5.9-py3-none-any.whl + hash: + sha256: 540f85f490b00abcd29237a6bf39967fea85cac452f1262a762a6667bf0a5f7a + category: main + optional: false +- name: whylogs + version: 1.3.3 + manager: pip + platform: linux-64 + dependencies: + platformdirs: '>=3.5.0,<4.0.0' + protobuf: '>=3.19.4' + requests: '>=2.27,<3.0' + types-requests: '>=2.30.0.0,<3.0.0.0' + typing-extensions: '>=3.10' + whylabs-client: '>=0.5.5,<0.6.0' + whylogs-sketching: '>=3.4.1.dev3' + url: https://files.pythonhosted.org/packages/91/cc/2c90e7ef06e940bf912d5b0a7373b9f15547efdf07a38ddcc6e739d9981b/whylogs-1.3.3-py3-none-any.whl + hash: + sha256: 8aeab6ff2634a6bbf2adc5b6ee34b2e29eadecfb64a5f50f1a95b1b28b358531 + category: main + optional: false +- name: whylogs + version: 1.3.3 + manager: pip + platform: osx-arm64 + dependencies: + platformdirs: '>=3.5.0,<4.0.0' + protobuf: '>=3.19.4' + requests: '>=2.27,<3.0' + types-requests: '>=2.30.0.0,<3.0.0.0' + typing-extensions: '>=3.10' + whylabs-client: '>=0.5.5,<0.6.0' + whylogs-sketching: '>=3.4.1.dev3' + url: https://files.pythonhosted.org/packages/91/cc/2c90e7ef06e940bf912d5b0a7373b9f15547efdf07a38ddcc6e739d9981b/whylogs-1.3.3-py3-none-any.whl + hash: + sha256: 8aeab6ff2634a6bbf2adc5b6ee34b2e29eadecfb64a5f50f1a95b1b28b358531 + category: main + optional: false +- name: whylogs-sketching + version: 3.4.1.dev3 + manager: pip + platform: linux-64 + dependencies: {} + url: https://files.pythonhosted.org/packages/32/12/791cf3bb9203b23c9976b07ae8b612f63f79e2fc8d4897b21c7861f213a1/whylogs_sketching-3.4.1.dev3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + hash: + sha256: d1d6e7d0ddb66ab725d7af63518ef6a24cd45b075b81e1d2081709df4c989853 + category: main + optional: false +- name: whylogs-sketching + version: 3.4.1.dev3 + manager: pip + platform: osx-arm64 + dependencies: {} + url: https://files.pythonhosted.org/packages/11/50/4d2906066362827bf7b9cc116d6e796760cef9d27ee30230f16075283f09/whylogs_sketching-3.4.1.dev3-cp39-cp39-macosx_11_0_arm64.whl + hash: + sha256: cc81b547e331d96f6f4227280b9b5968ca4bd48dd7cb0c8b68c022037800009f + category: main + optional: false +- name: wordcloud + version: 1.9.2 + manager: pip + platform: linux-64 + dependencies: + numpy: '>=1.6.1' + pillow: '*' + matplotlib: '*' + url: https://files.pythonhosted.org/packages/80/4b/cc14e0247729101d429978b82ebf852eb2554ee5dd6cf41fff1f41b714fc/wordcloud-1.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + hash: + sha256: 91e025b5e50d814601703aa4878dbafdceaa0a3e64d42cd1633317d9b829bb64 + category: main + optional: false +- name: wordcloud + version: 1.9.2 + manager: pip + platform: osx-arm64 + dependencies: + numpy: '>=1.6.1' + pillow: '*' + matplotlib: '*' + url: https://files.pythonhosted.org/packages/fe/f9/35e6f31e57c2f51351625045c9d1ad2fc33fe79cac21973f8985c7dbcbb9/wordcloud-1.9.2.tar.gz + hash: + sha256: 71062ba6bfeaf1a7f8b6f18f6a8a7a810ef10973ebd9aa10c04d9fff690363d3 + category: main + optional: false +- name: ydata-profiling + version: 4.6.3 + manager: pip + platform: linux-64 + dependencies: + scipy: '>=1.4.1,<1.12' + pandas: '>1.1,<1.4.0 || >1.4.0,<3' + matplotlib: '>=3.2,<3.9' + pydantic: '>=2' + pyyaml: '>=5.0.0,<6.1' + jinja2: '>=2.11.1,<3.2' + visions: 0.7.5 + numpy: '>=1.16.0,<1.26' + htmlmin: 0.1.12 + phik: '>=0.11.1,<0.13' + requests: '>=2.24.0,<3' + tqdm: '>=4.48.2,<5' + seaborn: '>=0.10.1,<0.13' + multimethod: '>=1.4,<2' + statsmodels: '>=0.13.2,<1' + typeguard: '>=4.1.2,<5' + imagehash: 4.3.1 + wordcloud: '>=1.9.1' + dacite: '>=1.8' + numba: '>=0.56.0,<0.59.0' + url: https://files.pythonhosted.org/packages/c6/12/a869b9f81c992a179a27d76154b3ae3c1a65a43c9ec117437762093a75ca/ydata_profiling-4.6.3-py2.py3-none-any.whl + hash: + sha256: 156d68a20f1a1de4c449177291e4eed07e46429d332d162243d8bf2c61f60903 + category: main + optional: false +- name: ydata-profiling + version: 4.6.3 + manager: pip + platform: osx-arm64 + dependencies: + scipy: '>=1.4.1,<1.12' + pandas: '>1.1,<1.4.0 || >1.4.0,<3' + matplotlib: '>=3.2,<3.9' + pydantic: '>=2' + pyyaml: '>=5.0.0,<6.1' + jinja2: '>=2.11.1,<3.2' + visions: 0.7.5 + numpy: '>=1.16.0,<1.26' + htmlmin: 0.1.12 + phik: '>=0.11.1,<0.13' + requests: '>=2.24.0,<3' + tqdm: '>=4.48.2,<5' + seaborn: '>=0.10.1,<0.13' + multimethod: '>=1.4,<2' + statsmodels: '>=0.13.2,<1' + typeguard: '>=4.1.2,<5' + imagehash: 4.3.1 + wordcloud: '>=1.9.1' + dacite: '>=1.8' + numba: '>=0.56.0,<0.59.0' + url: https://files.pythonhosted.org/packages/c6/12/a869b9f81c992a179a27d76154b3ae3c1a65a43c9ec117437762093a75ca/ydata_profiling-4.6.3-py2.py3-none-any.whl + hash: + sha256: 156d68a20f1a1de4c449177291e4eed07e46429d332d162243d8bf2c61f60903 + category: main + optional: false diff --git a/monodocs-environment.yaml b/monodocs-environment.yaml index 335f8584e4..2f493af3c2 100644 --- a/monodocs-environment.yaml +++ b/monodocs-environment.yaml @@ -1,3 +1,4 @@ +name: monodocs-env channels: - conda-forge dependencies: @@ -71,3 +72,7 @@ dependencies: - whylabs-client # whylogs - ray==2.6.3 - duckdb + +platforms: + - linux-64 + - osx-arm64

3n7q1E7jshN918}Dg_kKa( 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