From cc37a3de1e43f0ca39eb4ab3aa3260d68207e799 Mon Sep 17 00:00:00 2001 From: Attila Toth Date: Tue, 20 Jun 2023 15:04:27 +0200 Subject: [PATCH 001/113] Add ScyllaDB docs --- docs/SUMMARY.md | 1 + docs/reference/online-stores/README.md | 3 + docs/reference/online-stores/scylladb.md | 94 ++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 docs/reference/online-stores/scylladb.md diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 9b22d1e2865..9b781500b0f 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -98,6 +98,7 @@ * [MySQL (contrib)](reference/online-stores/mysql.md) * [Rockset (contrib)](reference/online-stores/rockset.md) * [Hazelcast (contrib)](reference/online-stores/hazelcast.md) + [ScyllaDB (contrib)](reference/online-stores/scylladb.md) * [Providers](reference/providers/README.md) * [Local](reference/providers/local.md) * [Google Cloud Platform](reference/providers/google-cloud-platform.md) diff --git a/docs/reference/online-stores/README.md b/docs/reference/online-stores/README.md index 2fdfd50f7c1..dc66a89d940 100644 --- a/docs/reference/online-stores/README.md +++ b/docs/reference/online-stores/README.md @@ -50,4 +50,7 @@ Please see [Online Store](../../getting-started/architecture-and-components/onli [hazelcast.md](hazelcast.md) {% endcontent-ref %} +{% content-ref url="scylladb.md" %} +[scylladb.md](scylladb.md) +{% endcontent-ref %} diff --git a/docs/reference/online-stores/scylladb.md b/docs/reference/online-stores/scylladb.md new file mode 100644 index 00000000000..e28e810e214 --- /dev/null +++ b/docs/reference/online-stores/scylladb.md @@ -0,0 +1,94 @@ +# ScyllaDB Cloud online store + +## Description + +ScyllaDB is a low-latency and high-performance Cassandra-compatible (uses CQL) database. You can use the existing Cassandra connector to use ScyllaDB as an online store in Feast. + +The [ScyllaDB](https://www.scylladb.com/) online store provides support for materializing feature values into a ScyllaDB or [ScyllaDB Cloud](https://www.scylladb.com/product/scylla-cloud/) cluster for serving online features real-time. + +## Getting started + +Install Feast with Cassandra support: +```bash +pip install "feast[cassandra]" +``` + +Create a new Feast project: +```bash +feast init REPO_NAME -t cassandra +``` + +### Example (ScyllaDB) + +{% code title="feature_store.yaml" %} +```yaml +project: scylla_feature_repo +registry: data/registry.db +provider: local +online_store: + type: cassandra + hosts: + - 172.17.0.2 + keyspace: feast + username: scylla + password: password +``` +{% endcode %} + +### Example (ScyllaDB Cloud) + +{% code title="feature_store.yaml" %} +```yaml +project: scylla_feature_repo +registry: data/registry.db +provider: local +online_store: + type: cassandra + hosts: + - node-0.aws_us_east_1.xxxxxxxx.clusters.scylla.cloud + - node-1.aws_us_east_1.xxxxxxxx.clusters.scylla.cloud + - node-2.aws_us_east_1.xxxxxxxx.clusters.scylla.cloud + keyspace: feast + username: scylla + password: password +``` +{% endcode %} + + +The full set of configuration options is available in [CassandraOnlineStoreConfig](https://rtd.feast.dev/en/master/#feast.infra.online_stores.contrib.cassandra_online_store.cassandra_online_store.CassandraOnlineStoreConfig). +For a full explanation of configuration options please look at file +`sdk/python/feast/infra/online_stores/contrib/cassandra_online_store/README.md`. + +Storage specifications can be found at `docs/specs/online_store_format.md`. + +## Functionality Matrix + +The set of functionality supported by online stores is described in detail [here](overview.md#functionality). +Below is a matrix indicating which functionality is supported by the Cassandra plugin. + +| | Cassandra | +| :-------------------------------------------------------- | :-------- | +| write feature values to the online store | yes | +| read feature values from the online store | yes | +| update infrastructure (e.g. tables) in the online store | yes | +| teardown infrastructure (e.g. tables) in the online store | yes | +| generate a plan of infrastructure changes | yes | +| support for on-demand transforms | yes | +| readable by Python SDK | yes | +| readable by Java | no | +| readable by Go | no | +| support for entityless feature views | yes | +| support for concurrent writing to the same key | no | +| support for ttl (time to live) at retrieval | no | +| support for deleting expired data | no | +| collocated by feature view | yes | +| collocated by feature service | no | +| collocated by entity key | no | + +To compare this set of functionality against other online stores, please see the full [functionality matrix](overview.md#functionality-matrix). + +## Resources + +* [Sample application with ScyllaDB](https://feature-store.scylladb.com/stable/) +* [ScyllaDB website](https://www.scylladb.com/) +* [ScyllaDB Cloud documentation](https://cloud.docs.scylladb.com/stable/) From c25c62b7e239e1c0e0071996bd0559916355b695 Mon Sep 17 00:00:00 2001 From: Attila Toth Date: Tue, 20 Jun 2023 15:06:09 +0200 Subject: [PATCH 002/113] Formatting Signed-off-by: Attila Toth --- docs/SUMMARY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 9b781500b0f..bf46f17060a 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -98,7 +98,7 @@ * [MySQL (contrib)](reference/online-stores/mysql.md) * [Rockset (contrib)](reference/online-stores/rockset.md) * [Hazelcast (contrib)](reference/online-stores/hazelcast.md) - [ScyllaDB (contrib)](reference/online-stores/scylladb.md) + * [ScyllaDB (contrib)](reference/online-stores/scylladb.md) * [Providers](reference/providers/README.md) * [Local](reference/providers/local.md) * [Google Cloud Platform](reference/providers/google-cloud-platform.md) From a2723fdcf2508b5db49f05f97a18a71a35c9a22d Mon Sep 17 00:00:00 2001 From: Danny C Date: Mon, 3 Jul 2023 12:26:30 -0700 Subject: [PATCH 003/113] ci: Add bigtable cleanup script Signed-off-by: Danny C Signed-off-by: Attila Toth --- .github/workflows/nightly-ci.yml | 17 ++++++++-- infra/scripts/cleanup_ci.py | 50 ++++++++++++++++++++++++++++++ infra/scripts/cleanup_dynamo_ci.py | 22 ------------- 3 files changed, 64 insertions(+), 25 deletions(-) create mode 100644 infra/scripts/cleanup_ci.py delete mode 100644 infra/scripts/cleanup_dynamo_ci.py diff --git a/.github/workflows/nightly-ci.yml b/.github/workflows/nightly-ci.yml index 7a22435fda9..a0d1052fdb6 100644 --- a/.github/workflows/nightly-ci.yml +++ b/.github/workflows/nightly-ci.yml @@ -27,7 +27,7 @@ jobs: cleanup_dynamo_tables: if: github.repository == 'feast-dev/feast' runs-on: ubuntu-latest - name: Cleanup dynamo tables which can fail to cleanup + name: Cleanup Bigtable / Dynamo tables which can fail to cleanup steps: - uses: actions/checkout@v2 with: @@ -47,9 +47,20 @@ jobs: - name: Install Python dependencies run: | pip install boto3 + pip install google-cloud-bigtable pip install tqdm - - name: Run DynamoDB cleanup script - run: python infra/scripts/cleanup_dynamo_ci.py + - name: Authenticate to Google Cloud + uses: 'google-github-actions/auth@v1' + with: + credentials_json: '${{ secrets.GCP_SA_KEY }}' + - name: Set up gcloud SDK + uses: google-github-actions/setup-gcloud@v1 + with: + project_id: ${{ secrets.GCP_PROJECT_ID }} + - name: Use gcloud CLI + run: gcloud info + - name: Run DynamoDB / Bigtable cleanup script + run: python infra/scripts/cleanup_ci.py build-docker-image: if: github.repository == 'feast-dev/feast' needs: [check_date] diff --git a/infra/scripts/cleanup_ci.py b/infra/scripts/cleanup_ci.py new file mode 100644 index 00000000000..262adf1e3eb --- /dev/null +++ b/infra/scripts/cleanup_ci.py @@ -0,0 +1,50 @@ +from time import sleep +import boto3 +from tqdm import tqdm +from google.cloud import bigtable +from google.cloud.bigtable import enums + + +def cleanup_dynamo_ci(): + db = boto3.resource("dynamodb") + + num_to_delete = 0 + all_tables = db.tables.all() + for table in all_tables: + if "integration_test" in table.name: + num_to_delete += 1 + with tqdm(total=num_to_delete) as progress: + for table in all_tables: + if "integration_test" in table.name: + table.delete() + progress.update() + print(f"Deleted {num_to_delete} CI DynamoDB tables") + + +def cleanup_bigtable_ci(): + client = bigtable.Client(project="kf-feast", admin=True) + instance = client.instance("feast-integration-tests") + if instance.exists(): + print(f"Deleted Bigtable CI instance") + instance.delete() + + location_id = "us-central1-f" + serve_nodes = 1 + storage_type = enums.StorageType.SSD + cluster = instance.cluster( + "feast-integration-tests-c1", + location_id=location_id, + serve_nodes=serve_nodes, + default_storage_type=storage_type, + ) + instance.create(clusters=[cluster]) + print(f"Created new Bigtable CI tables") + + +def main() -> None: + cleanup_dynamo_ci() + cleanup_bigtable_ci() + + +if __name__ == "__main__": + main() diff --git a/infra/scripts/cleanup_dynamo_ci.py b/infra/scripts/cleanup_dynamo_ci.py deleted file mode 100644 index 2dda36cc5a5..00000000000 --- a/infra/scripts/cleanup_dynamo_ci.py +++ /dev/null @@ -1,22 +0,0 @@ -import boto3 -from tqdm import tqdm - - -def main() -> None: - db = boto3.resource("dynamodb") - - num_to_delete = 0 - all_tables = db.tables.all() - for table in all_tables: - if "integration_test" in table.name: - num_to_delete += 1 - with tqdm(total=num_to_delete) as progress: - for table in all_tables: - if "integration_test" in table.name: - table.delete() - progress.update() - print(f"Deleted {num_to_delete} CI DynamoDB tables") - - -if __name__ == "__main__": - main() From da96fd15f507a5539cfabc0580bbf736a3e63e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EA=B7=9C=EB=AF=BC?= <32768535+GyuminJack@users.noreply.github.com> Date: Tue, 4 Jul 2023 04:32:10 +0900 Subject: [PATCH 004/113] fix: Missing Catalog argument in athena connector (#3661) update Catalog argument in athena connector Signed-off-by: Gyumin Lee Co-authored-by: Gyumin Lee Signed-off-by: Attila Toth --- sdk/python/feast/infra/utils/aws_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/feast/infra/utils/aws_utils.py b/sdk/python/feast/infra/utils/aws_utils.py index 5095ef42219..f48dfbb86b4 100644 --- a/sdk/python/feast/infra/utils/aws_utils.py +++ b/sdk/python/feast/infra/utils/aws_utils.py @@ -755,7 +755,7 @@ def execute_athena_query_async( # return athena_data_client.execute_statement( return athena_data_client.start_query_execution( QueryString=query, - QueryExecutionContext={"Database": database}, + QueryExecutionContext={"Database": database, "Catalog": data_source}, WorkGroup=workgroup, ) From d3d2d3f70b382e7acf12109aa21db0e62f80b1c3 Mon Sep 17 00:00:00 2001 From: Danny C Date: Mon, 3 Jul 2023 15:16:09 -0700 Subject: [PATCH 005/113] ci: Disable flaky lambda materialization test Signed-off-by: Danny C Signed-off-by: Attila Toth --- sdk/python/tests/integration/materialization/test_lambda.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/tests/integration/materialization/test_lambda.py b/sdk/python/tests/integration/materialization/test_lambda.py index d93508c156a..07ab93e2e13 100644 --- a/sdk/python/tests/integration/materialization/test_lambda.py +++ b/sdk/python/tests/integration/materialization/test_lambda.py @@ -21,6 +21,7 @@ @pytest.mark.integration +@pytest.mark.skip(reason="Very flaky test") def test_lambda_materialization_consistency(): lambda_config = IntegrationTestRepoConfig( provider="aws", @@ -64,7 +65,6 @@ def test_lambda_materialization_consistency(): ) try: - fs.apply([driver, driver_stats_fv]) print(df) From 3790e18fd27f79dd3b3e1034a087bbfa5f7823dc Mon Sep 17 00:00:00 2001 From: Ben Fletcher Date: Mon, 3 Jul 2023 23:52:40 +0100 Subject: [PATCH 006/113] fix: Broken non-root path with projects-list.json (#3665) ensure correct precedence with the two operators Signed-off-by: Ben Fletcher Signed-off-by: Attila Toth --- ui/src/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/index.tsx b/ui/src/index.tsx index 82c709d5d39..7559d02ebfd 100644 --- a/ui/src/index.tsx +++ b/ui/src/index.tsx @@ -97,7 +97,7 @@ ReactDOM.render( reactQueryClient={queryClient} feastUIConfigs={{ tabsRegistry: tabsRegistry, - projectListPromise: fetch(process.env.PUBLIC_URL || "" + "/projects-list.json", { + projectListPromise: fetch((process.env.PUBLIC_URL || "") + "/projects-list.json", { headers: { "Content-Type": "application/json", }, From 15d425f47e8272eb99f495fe170a611e69559c0c Mon Sep 17 00:00:00 2001 From: Jiwon Park Date: Tue, 4 Jul 2023 09:55:26 +0900 Subject: [PATCH 007/113] fix: Manage redis pipe's context (#3655) Signed-off-by: Jiwon Park Signed-off-by: Attila Toth --- sdk/python/feast/infra/online_stores/redis.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sdk/python/feast/infra/online_stores/redis.py b/sdk/python/feast/infra/online_stores/redis.py index 8af20970764..83922068ac4 100644 --- a/sdk/python/feast/infra/online_stores/redis.py +++ b/sdk/python/feast/infra/online_stores/redis.py @@ -89,15 +89,15 @@ class RedisOnlineStore(OnlineStore): def delete_entity_values(self, config: RepoConfig, join_keys: List[str]): client = self._get_client(config.online_store) deleted_count = 0 - pipeline = client.pipeline(transaction=False) prefix = _redis_key_prefix(join_keys) - for _k in client.scan_iter( - b"".join([prefix, b"*", config.project.encode("utf8")]) - ): - pipeline.delete(_k) - deleted_count += 1 - pipeline.execute() + with client.pipeline(transaction=False) as pipe: + for _k in client.scan_iter( + b"".join([prefix, b"*", config.project.encode("utf8")]) + ): + pipe.delete(_k) + deleted_count += 1 + pipe.execute() logger.debug(f"Deleted {deleted_count} rows for entity {', '.join(join_keys)}") From b6b74ba0dc50ef7a4d638c95815015183413ba7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 08:39:15 -0700 Subject: [PATCH 008/113] chore: Bump tough-cookie from 4.0.0 to 4.1.3 in /sdk/python/feast/ui (#3677) Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 4.0.0 to 4.1.3. - [Release notes](https://github.com/salesforce/tough-cookie/releases) - [Changelog](https://github.com/salesforce/tough-cookie/blob/master/CHANGELOG.md) - [Commits](https://github.com/salesforce/tough-cookie/compare/v4.0.0...v4.1.3) --- updated-dependencies: - dependency-name: tough-cookie dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/feast/ui/yarn.lock | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/sdk/python/feast/ui/yarn.lock b/sdk/python/feast/ui/yarn.lock index b375ef68813..0317b7a3dae 100644 --- a/sdk/python/feast/ui/yarn.lock +++ b/sdk/python/feast/ui/yarn.lock @@ -9761,13 +9761,14 @@ toidentifier@1.0.1: integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== dependencies: psl "^1.1.33" punycode "^2.1.1" - universalify "^0.1.2" + universalify "^0.2.0" + url-parse "^1.5.3" tr46@^1.0.1: version "1.0.1" @@ -10021,10 +10022,10 @@ unist-util-visit@^2.0.0, unist-util-visit@^2.0.3: unist-util-is "^4.0.0" unist-util-visit-parents "^3.0.0" -universalify@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== universalify@^2.0.0: version "2.0.0" @@ -10061,7 +10062,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -url-parse@^1.5.10: +url-parse@^1.5.10, url-parse@^1.5.3: version "1.5.10" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== From f671c0a81fd9319c94013923c49045997206378a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 10:15:15 -0700 Subject: [PATCH 009/113] chore: Bump tough-cookie from 4.0.0 to 4.1.3 in /ui (#3676) Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 4.0.0 to 4.1.3. - [Release notes](https://github.com/salesforce/tough-cookie/releases) - [Changelog](https://github.com/salesforce/tough-cookie/blob/master/CHANGELOG.md) - [Commits](https://github.com/salesforce/tough-cookie/compare/v4.0.0...v4.1.3) --- updated-dependencies: - dependency-name: tough-cookie dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- ui/yarn.lock | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/ui/yarn.lock b/ui/yarn.lock index db6dacc906e..1423b43fed5 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -10740,13 +10740,14 @@ toidentifier@1.0.1: integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== dependencies: psl "^1.1.33" punycode "^2.1.1" - universalify "^0.1.2" + universalify "^0.2.0" + url-parse "^1.5.3" tr46@^1.0.1: version "1.0.1" @@ -11030,11 +11031,16 @@ unist-util-visit@^2.0.0, unist-util-visit@^2.0.3: unist-util-is "^4.0.0" unist-util-visit-parents "^3.0.0" -universalify@^0.1.0, universalify@^0.1.2: +universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== + universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" @@ -11070,7 +11076,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -url-parse@^1.5.10: +url-parse@^1.5.10, url-parse@^1.5.3: version "1.5.10" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== From 6bfbc87c9a62b15df4d1da28bf23beaa32a5383f Mon Sep 17 00:00:00 2001 From: Ross Donnachie Date: Thu, 13 Jul 2023 08:06:45 +0200 Subject: [PATCH 010/113] fix: For SQL registry, increase max data_source_name length to 255 (#3630) * sql.py data_sources.data_source_name String(255) Extend the limit of the data_source_name field from 50 to 255. Signed-off-by: Ross Donnachie Signed-off-by: Attila Toth --- sdk/python/feast/infra/registry/sql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/feast/infra/registry/sql.py b/sdk/python/feast/infra/registry/sql.py index 54ff7c9dc85..d57bcc7c0a3 100644 --- a/sdk/python/feast/infra/registry/sql.py +++ b/sdk/python/feast/infra/registry/sql.py @@ -81,7 +81,7 @@ data_sources = Table( "data_sources", metadata, - Column("data_source_name", String(50), primary_key=True), + Column("data_source_name", String(255), primary_key=True), Column("project_id", String(50), primary_key=True), Column("last_updated_timestamp", BigInteger, nullable=False), Column("data_source_proto", LargeBinary, nullable=False), From f776400f3c2fd45b0f8d9a3bdbddef78dbe3a8e1 Mon Sep 17 00:00:00 2001 From: Harry Date: Thu, 13 Jul 2023 13:07:41 +0700 Subject: [PATCH 011/113] fix: Optimize bytes processed when retrieving entity df schema to 0 (#3680) feat: Optimize bytes processed when retrieving entity df schema to 0 Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- sdk/python/feast/infra/offline_stores/bigquery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/feast/infra/offline_stores/bigquery.py b/sdk/python/feast/infra/offline_stores/bigquery.py index 47335c411fd..5dd8f61bced 100644 --- a/sdk/python/feast/infra/offline_stores/bigquery.py +++ b/sdk/python/feast/infra/offline_stores/bigquery.py @@ -693,7 +693,7 @@ def _get_entity_schema( ) -> Dict[str, np.dtype]: if isinstance(entity_df, str): entity_df_sample = ( - client.query(f"SELECT * FROM ({entity_df}) LIMIT 1").result().to_dataframe() + client.query(f"SELECT * FROM ({entity_df}) LIMIT 0").result().to_dataframe() ) entity_schema = dict(zip(entity_df_sample.columns, entity_df_sample.dtypes)) From f604e40d4b4206b0441db225ba9a3e62e7268e7b Mon Sep 17 00:00:00 2001 From: William Foschiera Date: Thu, 13 Jul 2023 02:08:38 -0400 Subject: [PATCH 012/113] fix: Entityless fv breaks with `KeyError: __dummy` applying feature_store.plan() on python (#3640) * fix! KeyError: __dummy on entityless fv Signed-off-by: williamfoschiera * fix! join_keys typing. Signed-off-by: williamfoschiera --------- Signed-off-by: williamfoschiera Co-authored-by: williamfoschiera Signed-off-by: Attila Toth --- sdk/python/feast/inference.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sdk/python/feast/inference.py b/sdk/python/feast/inference.py index d416763bd39..28a170172c8 100644 --- a/sdk/python/feast/inference.py +++ b/sdk/python/feast/inference.py @@ -1,5 +1,5 @@ import re -from typing import List, Set, Union +from typing import List, Optional, Set, Union from feast.data_source import DataSource, PushSource, RequestSource from feast.entity import Entity @@ -119,7 +119,10 @@ def update_feature_views_with_inferred_features_and_entities( for fv in fvs: join_keys = set( - [entity_name_to_join_key_map[entity_name] for entity_name in fv.entities] + [ + entity_name_to_join_key_map.get(entity_name) + for entity_name in fv.entities + ] ) # Fields whose names match a join key are considered to be entity columns; all @@ -137,7 +140,10 @@ def update_feature_views_with_inferred_features_and_entities( # Respect the `value_type` attribute of the entity, if it is specified. for entity_name in fv.entities: - entity = entity_name_to_entity_map[entity_name] + entity = entity_name_to_entity_map.get(entity_name) + # pass when entity does not exist. Entityless feature view case + if entity is None: + continue if ( entity.join_key not in [entity_column.name for entity_column in fv.entity_columns] @@ -181,7 +187,7 @@ def update_feature_views_with_inferred_features_and_entities( def _infer_features_and_entities( fv: FeatureView, - join_keys: Set[str], + join_keys: Set[Optional[str]], run_inference_for_features, config, ) -> None: From 79e8fc85aadba3ea4405b948a0ec872e0bf69b30 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 16 Jul 2023 19:24:39 -0700 Subject: [PATCH 013/113] chore: Bump protobufjs from 7.1.1 to 7.2.4 in /ui (#3674) Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 7.1.1 to 7.2.4. - [Release notes](https://github.com/protobufjs/protobuf.js/releases) - [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.1.1...protobufjs-v7.2.4) --- updated-dependencies: - dependency-name: protobufjs dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- ui/yarn.lock | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/ui/yarn.lock b/ui/yarn.lock index 1423b43fed5..a4dc4931e46 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2576,12 +2576,7 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== -"@types/node@*": - version "17.0.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.13.tgz#5ed7ed7c662948335fcad6c412bb42d99ea754e3" - integrity sha512-Y86MAxASe25hNzlDbsviXl8jQHb0RDvKt4c40ZJQ1Don0AAL0STLZSs4N+6gLEO55pedy7r2cLwS+ZDxPm/2Bw== - -"@types/node@>=13.7.0": +"@types/node@*", "@types/node@>=13.7.0": version "18.7.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.18.tgz#633184f55c322e4fb08612307c274ee6d5ed3154" integrity sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg== @@ -9048,9 +9043,9 @@ protobufjs-cli@^1.0.2: uglify-js "^3.7.7" protobufjs@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.1.1.tgz#0117befb4b0f5a49d028e93f2ca62c3c1f5e7c65" - integrity sha512-d0nMQqS/aT3lfV8bKi9Gbg73vPd2LcDdTDOu6RE/M+h9DY8g1EmDzk3ADPccthEWfTBjkR2oxNdx9Gs8YubT+g== + version "7.2.4" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.4.tgz#3fc1ec0cdc89dd91aef9ba6037ba07408485c3ae" + integrity sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" From 854ea8b21ce5eea12b7937792639e787689aa34d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 16 Jul 2023 19:25:23 -0700 Subject: [PATCH 014/113] chore: Bump protobufjs from 7.1.2 to 7.2.4 in /sdk/python/feast/ui (#3675) Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 7.1.2 to 7.2.4. - [Release notes](https://github.com/protobufjs/protobuf.js/releases) - [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.1.2...protobufjs-v7.2.4) --- updated-dependencies: - dependency-name: protobufjs dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/feast/ui/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/feast/ui/yarn.lock b/sdk/python/feast/ui/yarn.lock index 0317b7a3dae..2fdcfa95883 100644 --- a/sdk/python/feast/ui/yarn.lock +++ b/sdk/python/feast/ui/yarn.lock @@ -8272,9 +8272,9 @@ property-information@^5.0.0, property-information@^5.3.0: xtend "^4.0.0" protobufjs@^7.1.1: - version "7.1.2" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.1.2.tgz#a0cf6aeaf82f5625bffcf5a38b7cd2a7de05890c" - integrity sha512-4ZPTPkXCdel3+L81yw3dG6+Kq3umdWKh7Dc7GW/CpNk4SX3hK58iPCWeCyhVTDrbkNeKrYNZ7EojM5WDaEWTLQ== + version "7.2.4" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.4.tgz#3fc1ec0cdc89dd91aef9ba6037ba07408485c3ae" + integrity sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" From aa235f8fbadde5417737650fd70f2969cc230bbd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 16 Jul 2023 19:26:53 -0700 Subject: [PATCH 015/113] chore: Bump semver from 6.3.0 to 6.3.1 in /ui (#3678) Bumps [semver](https://github.com/npm/node-semver) from 6.3.0 to 6.3.1. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/v6.3.1/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v6.3.0...v6.3.1) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- ui/yarn.lock | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/ui/yarn.lock b/ui/yarn.lock index a4dc4931e46..49bff13372a 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -9982,21 +9982,14 @@ semver@7.0.0: integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.1.2: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== - dependencies: - lru-cache "^6.0.0" + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.2, semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== +semver@^7.1.2, semver@^7.3.2, semver@^7.3.5: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" From 24742464ca7d47a9194692b1fe9160a928e43d19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 16 Jul 2023 19:27:09 -0700 Subject: [PATCH 016/113] chore: Bump semver from 6.3.0 to 6.3.1 in /sdk/python/feast/ui (#3679) Bumps [semver](https://github.com/npm/node-semver) from 6.3.0 to 6.3.1. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/v6.3.1/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v6.3.0...v6.3.1) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/feast/ui/yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/python/feast/ui/yarn.lock b/sdk/python/feast/ui/yarn.lock index 2fdcfa95883..5ae42761adf 100644 --- a/sdk/python/feast/ui/yarn.lock +++ b/sdk/python/feast/ui/yarn.lock @@ -9103,14 +9103,14 @@ semver@7.0.0: integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.3.2, semver@^7.3.5: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" From b879056e85b3589eb384c889a1437888fe306e5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 16 Jul 2023 19:28:04 -0700 Subject: [PATCH 017/113] chore: Bump google.golang.org/grpc from 1.47.0 to 1.53.0 (#3670) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.47.0 to 1.53.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.47.0...v1.53.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- go.mod | 11 +- go.sum | 911 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 900 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index a051a13f6fe..68d47d70701 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ replace github.com/go-python/gopy v0.4.4 => github.com/feast-dev/gopy v0.4.1-0.2 require ( github.com/apache/arrow/go/v8 v8.0.0 github.com/ghodss/yaml v1.0.0 - github.com/go-python/gopy v0.4.4 github.com/go-redis/redis/v8 v8.11.4 github.com/golang/protobuf v1.5.2 github.com/google/uuid v1.3.0 @@ -15,21 +14,19 @@ require ( github.com/pkg/errors v0.9.1 github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.7.0 - google.golang.org/grpc v1.47.0 - google.golang.org/protobuf v1.28.0 + google.golang.org/grpc v1.53.0 + google.golang.org/protobuf v1.28.1 ) require ( github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect github.com/andybalholm/brotli v1.0.4 // indirect github.com/apache/thrift v0.15.0 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/goccy/go-json v0.9.6 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/gonuts/commander v0.1.0 // indirect - github.com/gonuts/flag v0.1.0 // indirect github.com/google/flatbuffers v2.0.6+incompatible // indirect github.com/klauspost/asmfmt v1.3.2 // indirect github.com/klauspost/compress v1.15.1 // indirect @@ -46,7 +43,7 @@ require ( golang.org/x/text v0.7.0 // indirect golang.org/x/tools v0.1.12 // indirect golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect - google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect diff --git a/go.sum b/go.sum index cbcfc75ac44..a2c7501e82b 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,389 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= @@ -42,21 +426,31 @@ github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -81,14 +475,17 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/feast-dev/gopy v0.4.1-0.20220714211711-252048177d85 h1:BKmfqWiDbxvviB6vemPbbNjF+ywRsBMCdk1QvrcGgkc= -github.com/feast-dev/gopy v0.4.1-0.20220714211711-252048177d85/go.mod h1:tlA/KcD7rM8B+NQJR4SASwiinfKY0aiMFanHszR8BZA= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -103,6 +500,7 @@ github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3 github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -125,14 +523,26 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -142,15 +552,13 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gonuts/commander v0.1.0 h1:EcDTiVw9oAVORFjQOEOuHQqcl6OXMyTgELocTq6zJ0I= -github.com/gonuts/commander v0.1.0/go.mod h1:qkb5mSlcWodYgo7vs8ulLnXhfinhZsZcm6+H/z1JjgY= -github.com/gonuts/flag v0.1.0 h1:fqMv/MZ+oNGu0i9gp0/IQ/ZaPIDoAZBOBaJoV7viCWM= -github.com/gonuts/flag v0.1.0/go.mod h1:ZTmTGtrSPejTo/SRNhCqwLTmiAgyBdCkLYhHrAoBdz4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/flatbuffers v2.0.5+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= @@ -160,17 +568,58 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -180,6 +629,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -202,6 +653,9 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -209,6 +663,8 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= @@ -225,6 +681,7 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -234,6 +691,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -308,6 +767,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -320,6 +781,7 @@ github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= @@ -349,6 +811,9 @@ github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -357,17 +822,29 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= @@ -379,13 +856,21 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -402,17 +887,29 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20211216164055-b2b84827b756/go.mod h1:b9TAUYHmRtqA6klRHApnXMnj+OyLce4yF5cZCUbk2ps= golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4 h1:K3x+yU+fbot38x5bQbU2QqUAVyYLEktdNH2GxZLnM3U= golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= @@ -429,20 +926,35 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -455,34 +967,99 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -496,45 +1073,104 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -546,27 +1182,74 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.11-0.20220413170336-afc6aad76eb1/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.9.3 h1:DnoIG+QAMaF5NvxnGe/oKsgKcAc6PcUyl8q0VetfQ8s= @@ -575,37 +1258,224 @@ gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6d gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac h1:qSNTkEN+L2mvWcLgJOR+8bdHX9rN/IdU3A1Ghpfb1Rg= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -614,12 +1484,14 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -643,11 +1515,20 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From 82e4c7f37bdbc444d42c476d389b306abebfd76c Mon Sep 17 00:00:00 2001 From: feast-ci-bot Date: Mon, 17 Jul 2023 02:57:06 +0000 Subject: [PATCH 018/113] chore(release): release 0.32.0 # [0.32.0](https://github.com/feast-dev/feast/compare/v0.31.0...v0.32.0) (2023-07-17) ### Bug Fixes * Added generic Feature store Creation for CLI ([#3618](https://github.com/feast-dev/feast/issues/3618)) ([bf740d2](https://github.com/feast-dev/feast/commit/bf740d2d0ef3b62cf27f25083b5b4d49955b56fb)) * Broken non-root path with projects-list.json ([#3665](https://github.com/feast-dev/feast/issues/3665)) ([4861af0](https://github.com/feast-dev/feast/commit/4861af0f3206f965ad2f7a4eddf2ebec2df149f8)) * Clean up snowflake to_spark_df() ([#3607](https://github.com/feast-dev/feast/issues/3607)) ([e8e643e](https://github.com/feast-dev/feast/commit/e8e643e3555127daf37fa4961fdadb0508a041db)) * Entityless fv breaks with `KeyError: __dummy` applying feature_store.plan() on python ([#3640](https://github.com/feast-dev/feast/issues/3640)) ([ef4ef32](https://github.com/feast-dev/feast/commit/ef4ef32f7466b5d874d537abe8def4731b15dc85)) * Fix scan datasize to 0 for inference schema ([#3628](https://github.com/feast-dev/feast/issues/3628)) ([c3dd74e](https://github.com/feast-dev/feast/commit/c3dd74e238b5b9e784e3dbe102941c66a63f6686)) * Fix timestamp consistency in push api ([#3614](https://github.com/feast-dev/feast/issues/3614)) ([9b227d7](https://github.com/feast-dev/feast/commit/9b227d7d44f30d28d1faadc8015f25dc4a6f56b5)) * For SQL registry, increase max data_source_name length to 255 ([#3630](https://github.com/feast-dev/feast/issues/3630)) ([478caec](https://github.com/feast-dev/feast/commit/478caecc8d61b6070ec03bc13688a83b8c5f5936)) * Implements connection pool for postgres online store ([#3633](https://github.com/feast-dev/feast/issues/3633)) ([059509a](https://github.com/feast-dev/feast/commit/059509a492d180effb1786713738665e293838e7)) * Manage redis pipe's context ([#3655](https://github.com/feast-dev/feast/issues/3655)) ([48e0971](https://github.com/feast-dev/feast/commit/48e097130e68241e751bd4be5af7427fffad47cf)) * Missing Catalog argument in athena connector ([#3661](https://github.com/feast-dev/feast/issues/3661)) ([f6d3caf](https://github.com/feast-dev/feast/commit/f6d3caf8affc74aef7ac489d3e6816d45b30d820)) * Optimize bytes processed when retrieving entity df schema to 0 ([#3680](https://github.com/feast-dev/feast/issues/3680)) ([1c01035](https://github.com/feast-dev/feast/commit/1c010357affd48616d39f1ad01b872fac946269d)) ### Features * Add gunicorn for serve with multiprocess ([#3636](https://github.com/feast-dev/feast/issues/3636)) ([4de7faf](https://github.com/feast-dev/feast/commit/4de7faf7b262d30a9f6795911d8fa97df775fa8d)) * Use string as a substitute for unregistered types during schema inference ([#3646](https://github.com/feast-dev/feast/issues/3646)) ([c474ccd](https://github.com/feast-dev/feast/commit/c474ccdd23ca8161de5e2958f0a12826c020dc44)) Signed-off-by: Attila Toth --- CHANGELOG.md | 23 ++ infra/charts/feast-feature-server/Chart.yaml | 2 +- infra/charts/feast-feature-server/README.md | 4 +- infra/charts/feast-feature-server/values.yaml | 2 +- infra/charts/feast/Chart.yaml | 2 +- infra/charts/feast/README.md | 6 +- .../feast/charts/feature-server/Chart.yaml | 4 +- .../feast/charts/feature-server/README.md | 4 +- .../feast/charts/feature-server/values.yaml | 2 +- .../charts/transformation-service/Chart.yaml | 4 +- .../charts/transformation-service/README.md | 4 +- .../charts/transformation-service/values.yaml | 2 +- infra/charts/feast/requirements.yaml | 4 +- java/pom.xml | 2 +- sdk/python/feast/ui/package.json | 2 +- sdk/python/feast/ui/yarn.lock | 366 +++++++++++++++++- ui/package.json | 2 +- 17 files changed, 402 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad30d312ee4..f21ecd9ff8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,28 @@ # Changelog +# [0.32.0](https://github.com/feast-dev/feast/compare/v0.31.0...v0.32.0) (2023-07-17) + + +### Bug Fixes + +* Added generic Feature store Creation for CLI ([#3618](https://github.com/feast-dev/feast/issues/3618)) ([bf740d2](https://github.com/feast-dev/feast/commit/bf740d2d0ef3b62cf27f25083b5b4d49955b56fb)) +* Broken non-root path with projects-list.json ([#3665](https://github.com/feast-dev/feast/issues/3665)) ([4861af0](https://github.com/feast-dev/feast/commit/4861af0f3206f965ad2f7a4eddf2ebec2df149f8)) +* Clean up snowflake to_spark_df() ([#3607](https://github.com/feast-dev/feast/issues/3607)) ([e8e643e](https://github.com/feast-dev/feast/commit/e8e643e3555127daf37fa4961fdadb0508a041db)) +* Entityless fv breaks with `KeyError: __dummy` applying feature_store.plan() on python ([#3640](https://github.com/feast-dev/feast/issues/3640)) ([ef4ef32](https://github.com/feast-dev/feast/commit/ef4ef32f7466b5d874d537abe8def4731b15dc85)) +* Fix scan datasize to 0 for inference schema ([#3628](https://github.com/feast-dev/feast/issues/3628)) ([c3dd74e](https://github.com/feast-dev/feast/commit/c3dd74e238b5b9e784e3dbe102941c66a63f6686)) +* Fix timestamp consistency in push api ([#3614](https://github.com/feast-dev/feast/issues/3614)) ([9b227d7](https://github.com/feast-dev/feast/commit/9b227d7d44f30d28d1faadc8015f25dc4a6f56b5)) +* For SQL registry, increase max data_source_name length to 255 ([#3630](https://github.com/feast-dev/feast/issues/3630)) ([478caec](https://github.com/feast-dev/feast/commit/478caecc8d61b6070ec03bc13688a83b8c5f5936)) +* Implements connection pool for postgres online store ([#3633](https://github.com/feast-dev/feast/issues/3633)) ([059509a](https://github.com/feast-dev/feast/commit/059509a492d180effb1786713738665e293838e7)) +* Manage redis pipe's context ([#3655](https://github.com/feast-dev/feast/issues/3655)) ([48e0971](https://github.com/feast-dev/feast/commit/48e097130e68241e751bd4be5af7427fffad47cf)) +* Missing Catalog argument in athena connector ([#3661](https://github.com/feast-dev/feast/issues/3661)) ([f6d3caf](https://github.com/feast-dev/feast/commit/f6d3caf8affc74aef7ac489d3e6816d45b30d820)) +* Optimize bytes processed when retrieving entity df schema to 0 ([#3680](https://github.com/feast-dev/feast/issues/3680)) ([1c01035](https://github.com/feast-dev/feast/commit/1c010357affd48616d39f1ad01b872fac946269d)) + + +### Features + +* Add gunicorn for serve with multiprocess ([#3636](https://github.com/feast-dev/feast/issues/3636)) ([4de7faf](https://github.com/feast-dev/feast/commit/4de7faf7b262d30a9f6795911d8fa97df775fa8d)) +* Use string as a substitute for unregistered types during schema inference ([#3646](https://github.com/feast-dev/feast/issues/3646)) ([c474ccd](https://github.com/feast-dev/feast/commit/c474ccdd23ca8161de5e2958f0a12826c020dc44)) + # [0.31.0](https://github.com/feast-dev/feast/compare/v0.30.0...v0.31.0) (2023-04-21) diff --git a/infra/charts/feast-feature-server/Chart.yaml b/infra/charts/feast-feature-server/Chart.yaml index 65dea258e09..e55bd86b544 100644 --- a/infra/charts/feast-feature-server/Chart.yaml +++ b/infra/charts/feast-feature-server/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: feast-feature-server description: Feast Feature Server in Go or Python type: application -version: 0.31.0 +version: 0.32.0 keywords: - machine learning - big data diff --git a/infra/charts/feast-feature-server/README.md b/infra/charts/feast-feature-server/README.md index e3515b10f8f..00ae16b0cd1 100644 --- a/infra/charts/feast-feature-server/README.md +++ b/infra/charts/feast-feature-server/README.md @@ -1,6 +1,6 @@ # Feast Python / Go Feature Server Helm Charts -Current chart version is `0.31.0` +Current chart version is `0.32.0` ## Installation @@ -30,7 +30,7 @@ See [here](https://github.com/feast-dev/feast/tree/master/examples/python-helm-d | fullnameOverride | string | `""` | | | image.pullPolicy | string | `"IfNotPresent"` | | | image.repository | string | `"feastdev/feature-server"` | Docker image for Feature Server repository | -| image.tag | string | `"0.31.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | +| image.tag | string | `"0.32.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | | imagePullSecrets | list | `[]` | | | livenessProbe.initialDelaySeconds | int | `30` | | | livenessProbe.periodSeconds | int | `30` | | diff --git a/infra/charts/feast-feature-server/values.yaml b/infra/charts/feast-feature-server/values.yaml index 8a66052861c..68c35175c47 100644 --- a/infra/charts/feast-feature-server/values.yaml +++ b/infra/charts/feast-feature-server/values.yaml @@ -9,7 +9,7 @@ image: repository: feastdev/feature-server pullPolicy: IfNotPresent # image.tag -- The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) - tag: 0.31.0 + tag: 0.32.0 imagePullSecrets: [] nameOverride: "" diff --git a/infra/charts/feast/Chart.yaml b/infra/charts/feast/Chart.yaml index 0daded67ed6..5b7817bdcb4 100644 --- a/infra/charts/feast/Chart.yaml +++ b/infra/charts/feast/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 description: Feature store for machine learning name: feast -version: 0.31.0 +version: 0.32.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index 17ba86b1d1a..777e036927d 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -8,7 +8,7 @@ This repo contains Helm charts for Feast Java components that are being installe ## Chart: Feast -Feature store for machine learning Current chart version is `0.31.0` +Feature store for machine learning Current chart version is `0.32.0` ## Installation @@ -65,8 +65,8 @@ See [here](https://github.com/feast-dev/feast/tree/master/examples/java-demo) fo | Repository | Name | Version | |------------|------|---------| | https://charts.helm.sh/stable | redis | 10.5.6 | -| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.31.0 | -| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.31.0 | +| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.32.0 | +| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.32.0 | ## Values diff --git a/infra/charts/feast/charts/feature-server/Chart.yaml b/infra/charts/feast/charts/feature-server/Chart.yaml index 78b83bb4f23..c4cd90a1e6b 100644 --- a/infra/charts/feast/charts/feature-server/Chart.yaml +++ b/infra/charts/feast/charts/feature-server/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 description: "Feast Feature Server: Online feature serving service for Feast" name: feature-server -version: 0.31.0 -appVersion: v0.31.0 +version: 0.32.0 +appVersion: v0.32.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/charts/feature-server/README.md b/infra/charts/feast/charts/feature-server/README.md index 237ed7b67ac..de4ff43e0dd 100644 --- a/infra/charts/feast/charts/feature-server/README.md +++ b/infra/charts/feast/charts/feature-server/README.md @@ -1,6 +1,6 @@ # feature-server -![Version: 0.31.0](https://img.shields.io/badge/Version-0.31.0-informational?style=flat-square) ![AppVersion: v0.31.0](https://img.shields.io/badge/AppVersion-v0.31.0-informational?style=flat-square) +![Version: 0.32.0](https://img.shields.io/badge/Version-0.32.0-informational?style=flat-square) ![AppVersion: v0.32.0](https://img.shields.io/badge/AppVersion-v0.32.0-informational?style=flat-square) Feast Feature Server: Online feature serving service for Feast @@ -17,7 +17,7 @@ Feast Feature Server: Online feature serving service for Feast | envOverrides | object | `{}` | Extra environment variables to set | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"feastdev/feature-server-java"` | Docker image for Feature Server repository | -| image.tag | string | `"0.31.0"` | Image tag | +| image.tag | string | `"0.32.0"` | Image tag | | ingress.grpc.annotations | object | `{}` | Extra annotations for the ingress | | ingress.grpc.auth.enabled | bool | `false` | Flag to enable auth | | ingress.grpc.class | string | `"nginx"` | Which ingress controller to use | diff --git a/infra/charts/feast/charts/feature-server/values.yaml b/infra/charts/feast/charts/feature-server/values.yaml index 054729f4784..5497aa74dc5 100644 --- a/infra/charts/feast/charts/feature-server/values.yaml +++ b/infra/charts/feast/charts/feature-server/values.yaml @@ -5,7 +5,7 @@ image: # image.repository -- Docker image for Feature Server repository repository: feastdev/feature-server-java # image.tag -- Image tag - tag: 0.31.0 + tag: 0.32.0 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/charts/transformation-service/Chart.yaml b/infra/charts/feast/charts/transformation-service/Chart.yaml index ecb02682f13..7bda807cf17 100644 --- a/infra/charts/feast/charts/transformation-service/Chart.yaml +++ b/infra/charts/feast/charts/transformation-service/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 description: "Transformation service: to compute on-demand features" name: transformation-service -version: 0.31.0 -appVersion: v0.31.0 +version: 0.32.0 +appVersion: v0.32.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/charts/transformation-service/README.md b/infra/charts/feast/charts/transformation-service/README.md index 64ebff9e9d4..121e24fe23f 100644 --- a/infra/charts/feast/charts/transformation-service/README.md +++ b/infra/charts/feast/charts/transformation-service/README.md @@ -1,6 +1,6 @@ # transformation-service -![Version: 0.31.0](https://img.shields.io/badge/Version-0.31.0-informational?style=flat-square) ![AppVersion: v0.31.0](https://img.shields.io/badge/AppVersion-v0.31.0-informational?style=flat-square) +![Version: 0.32.0](https://img.shields.io/badge/Version-0.32.0-informational?style=flat-square) ![AppVersion: v0.32.0](https://img.shields.io/badge/AppVersion-v0.32.0-informational?style=flat-square) Transformation service: to compute on-demand features @@ -13,7 +13,7 @@ Transformation service: to compute on-demand features | envOverrides | object | `{}` | Extra environment variables to set | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"feastdev/feature-transformation-server"` | Docker image for Transformation Server repository | -| image.tag | string | `"0.31.0"` | Image tag | +| image.tag | string | `"0.32.0"` | Image tag | | nodeSelector | object | `{}` | Node labels for pod assignment | | podLabels | object | `{}` | Labels to be added to Feast Serving pods | | replicaCount | int | `1` | Number of pods that will be created | diff --git a/infra/charts/feast/charts/transformation-service/values.yaml b/infra/charts/feast/charts/transformation-service/values.yaml index ecd9221eebb..f7acc7a1307 100644 --- a/infra/charts/feast/charts/transformation-service/values.yaml +++ b/infra/charts/feast/charts/transformation-service/values.yaml @@ -5,7 +5,7 @@ image: # image.repository -- Docker image for Transformation Server repository repository: feastdev/feature-transformation-server # image.tag -- Image tag - tag: 0.31.0 + tag: 0.32.0 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/requirements.yaml b/infra/charts/feast/requirements.yaml index 4d611f6fc8f..c04b3ee005b 100644 --- a/infra/charts/feast/requirements.yaml +++ b/infra/charts/feast/requirements.yaml @@ -1,12 +1,12 @@ dependencies: - name: feature-server alias: feature-server - version: 0.31.0 + version: 0.32.0 condition: feature-server.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: transformation-service alias: transformation-service - version: 0.31.0 + version: 0.32.0 condition: transformation-service.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: redis diff --git a/java/pom.xml b/java/pom.xml index edcd383e5b3..beaa5fb07e6 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -35,7 +35,7 @@ - 0.31.0 + 0.32.0 https://github.com/feast-dev/feast UTF-8 diff --git a/sdk/python/feast/ui/package.json b/sdk/python/feast/ui/package.json index 547e21b690e..0b22aff8844 100644 --- a/sdk/python/feast/ui/package.json +++ b/sdk/python/feast/ui/package.json @@ -6,7 +6,7 @@ "@elastic/datemath": "^5.0.3", "@elastic/eui": "^55.0.1", "@emotion/react": "^11.9.0", - "@feast-dev/feast-ui": "0.30.2", + "@feast-dev/feast-ui": "0.32.0", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.2.0", "@testing-library/user-event": "^13.5.0", diff --git a/sdk/python/feast/ui/yarn.lock b/sdk/python/feast/ui/yarn.lock index 5ae42761adf..a61d5a1bbf6 100644 --- a/sdk/python/feast/ui/yarn.lock +++ b/sdk/python/feast/ui/yarn.lock @@ -26,6 +26,13 @@ dependencies: "@babel/highlight" "^7.16.7" +"@babel/code-frame@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" + integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== + dependencies: + "@babel/highlight" "^7.22.5" + "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.17.0", "@babel/compat-data@^7.17.10": version "7.17.10" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.10.tgz#711dc726a492dfc8be8220028b1b92482362baab" @@ -70,6 +77,16 @@ "@jridgewell/gen-mapping" "^0.1.0" jsesc "^2.5.1" +"@babel/generator@^7.22.7": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" + integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== + dependencies: + "@babel/types" "^7.22.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" @@ -77,6 +94,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" @@ -137,6 +161,11 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== + "@babel/helper-explode-assignable-expression@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" @@ -152,6 +181,14 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.17.0" +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== + dependencies: + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" + "@babel/helper-hoist-variables@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" @@ -159,6 +196,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-member-expression-to-functions@^7.16.7", "@babel/helper-member-expression-to-functions@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz#a34013b57d8542a8c4ff8ba3f747c02452a4d8c4" @@ -166,6 +210,13 @@ dependencies: "@babel/types" "^7.17.0" +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" @@ -199,6 +250,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== +"@babel/helper-plugin-utils@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + "@babel/helper-remap-async-to-generator@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" @@ -240,11 +296,28 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + "@babel/helper-validator-option@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" @@ -278,11 +351,25 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" + integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.10": version "7.17.10" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.10.tgz#873b16db82a8909e0fbd7f115772f4b739f6ce78" integrity sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ== +"@babel/parser@^7.22.5", "@babel/parser@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" + integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050" @@ -516,6 +603,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-syntax-jsx@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" + integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" @@ -1025,6 +1119,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.10.4", "@babel/runtime@^7.3.1": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" + integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/template@^7.16.7", "@babel/template@^7.3.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" @@ -1034,6 +1135,15 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/template@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.10", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": version "7.17.10" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.10.tgz#1ee1a5ac39f4eac844e6cf855b35520e5eb6f8b5" @@ -1050,6 +1160,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.4.5": + version "7.22.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" + integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.7" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.7" + "@babel/types" "^7.22.5" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.17.10", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.17.10" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.10.tgz#d35d7b4467e439fcf06d195f8100e0fea7fc82c4" @@ -1058,6 +1184,15 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@babel/types@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" + integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + to-fast-properties "^2.0.0" + "@base2/pretty-print-object@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" @@ -1236,11 +1371,23 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== +"@emotion/is-prop-valid@^1.1.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" + integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/memoize@^0.7.4", "@emotion/memoize@^0.7.5": version "0.7.5" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50" integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ== +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + "@emotion/react@^11.7.1", "@emotion/react@^11.9.0": version "11.9.0" resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.9.0.tgz#b6d42b1db3bd7511e7a7c4151dc8bc82e14593b8" @@ -1270,7 +1417,12 @@ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.1.0.tgz#56d99c41f0a1cda2726a05aa6a20afd4c63e58d2" integrity sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g== -"@emotion/unitless@^0.7.5": +"@emotion/stylis@^0.8.4": + version "0.8.5" + resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" + integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== + +"@emotion/unitless@^0.7.4", "@emotion/unitless@^0.7.5": version "0.7.5" resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== @@ -1300,10 +1452,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@feast-dev/feast-ui@0.30.2": - version "0.30.2" - resolved "https://registry.yarnpkg.com/@feast-dev/feast-ui/-/feast-ui-0.30.2.tgz#867db94daba3dcb7d91f767bf104e489174dd666" - integrity sha512-qfsJYQb9eGaTLuk5tqi24nCE6YaP8SU8uf6ukENjj5Y8yRJhVy6IeZrIl/qpUsvAQd1PmmX0ZDr/zndD4QQsPA== +"@feast-dev/feast-ui@0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@feast-dev/feast-ui/-/feast-ui-0.32.0.tgz#fb10bd4ead0eb4edcf9d7a7fc357f50c0b9ff656" + integrity sha512-RL3qpZRdsfxMqb/4HqbeFC3qik1gK5cPo+EmdAe8YXJ2IBy2OXXrekHxf1nmNlLQ29Ogg9VZ/LyAmwa8A3LR5w== dependencies: "@elastic/datemath" "^5.0.3" "@elastic/eui" "^55.0.1" @@ -1319,6 +1471,7 @@ prop-types "^15.8.1" protobufjs "^7.1.1" query-string "^7.1.1" + react-code-blocks "^0.0.9-0" react-query "^3.34.12" react-router-dom "6" react-scripts "^5.0.0" @@ -1582,7 +1735,16 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== @@ -1605,11 +1767,19 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/trace-mapping@^0.3.17": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + "@jridgewell/trace-mapping@^0.3.9": version "0.3.14" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" @@ -3233,6 +3403,17 @@ babel-plugin-polyfill-regenerator@^0.3.0: dependencies: "@babel/helper-define-polyfill-provider" "^0.3.1" +"babel-plugin-styled-components@>= 1.12.0": + version "2.1.4" + resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz#9a1f37c7f32ef927b4b008b529feb4a2c82b1092" + integrity sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + lodash "^4.17.21" + picomatch "^2.3.1" + babel-plugin-transform-react-remove-prop-types@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" @@ -3479,6 +3660,11 @@ camelcase@^6.2.0, camelcase@^6.2.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +camelize@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" + integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== + caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -3616,6 +3802,15 @@ clean-css@^5.2.2: dependencies: source-map "~0.6.0" +clipboard@^2.0.0: + version "2.0.11" + resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.11.tgz#62180360b97dd668b6b3a84ec226975762a70be5" + integrity sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw== + dependencies: + good-listener "^1.2.2" + select "^1.1.2" + tiny-emitter "^2.0.0" + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -3862,6 +4057,11 @@ css-box-model@^1.2.0: dependencies: tiny-invariant "^1.0.6" +css-color-keywords@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" + integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg== + css-declaration-sorter@^6.2.2: version "6.2.2" resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.2.2.tgz#bfd2f6f50002d6a3ae779a87d3a0c5d5b10e0f02" @@ -3931,6 +4131,15 @@ css-select@^4.1.3: domutils "^2.8.0" nth-check "^2.0.1" +css-to-react-native@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz#cdd8099f71024e149e4f6fe17a7d46ecd55f1e32" + integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ== + dependencies: + camelize "^1.0.0" + css-color-keywords "^1.0.0" + postcss-value-parser "^4.0.2" + css-tree@1.0.0-alpha.37: version "1.0.0-alpha.37" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" @@ -4400,6 +4609,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= +delegate@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" + integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw== + depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -5127,6 +5341,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fault@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" + integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== + dependencies: + format "^0.2.0" + faye-websocket@^0.11.3: version "0.11.4" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" @@ -5297,6 +5518,11 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +format@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -5489,6 +5715,13 @@ globby@^11.0.4: merge2 "^1.4.1" slash "^3.0.0" +good-listener@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" + integrity sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw== + dependencies: + delegate "^3.1.2" + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" @@ -5636,6 +5869,16 @@ hast-util-whitespace@^1.0.0: resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz#e4fe77c4a9ae1cb2e6c25e02df0043d0164f6e41" integrity sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A== +hastscript@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.2.tgz#bde2c2e56d04c62dd24e8c5df288d050a355fb8a" + integrity sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ== + dependencies: + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" + space-separated-tokens "^1.0.0" + hastscript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" @@ -5652,6 +5895,11 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +highlight.js@~9.15.0, highlight.js@~9.15.1: + version "9.15.10" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.15.10.tgz#7b18ed75c90348c045eef9ed08ca1319a2219ad2" + integrity sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw== + history@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b" @@ -5659,7 +5907,7 @@ history@^5.2.0: dependencies: "@babel/runtime" "^7.7.6" -hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -6980,6 +7228,14 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lowlight@1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.12.1.tgz#014acf8dd73a370e02ff1cc61debcde3bb1681eb" + integrity sha512-OqaVxMGIESnawn+TU/QMV5BJLbUghUfjDWPAtFqDYDmDtr4FnB+op8xM+pR7nKlauHNUHXGt0VgWatFB8voS5w== + dependencies: + fault "^1.0.2" + highlight.js "~9.15.0" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -7540,6 +7796,18 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-entities@^1.1.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50" + integrity sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg== + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + parse-entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" @@ -8166,7 +8434,7 @@ postcss-unique-selectors@^5.1.1: dependencies: postcss-selector-parser "^6.0.5" -postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: +postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== @@ -8230,6 +8498,18 @@ pretty-format@^28.1.0: ansi-styles "^5.0.0" react-is "^18.0.0" +prismjs@^1.8.4: + version "1.29.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" + integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== + +prismjs@~1.17.0: + version "1.17.1" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.17.1.tgz#e669fcbd4cdd873c35102881c33b14d0d68519be" + integrity sha512-PrEDJAFdUGbOP6xK/UsfkC5ghJsPJviKgnQOoxaDbBjwc8op68Quupwt1DeAFoG8GImPhiKXAvvsH7wDSLsu1Q== + optionalDependencies: + clipboard "^2.0.0" + prismjs@~1.27.0: version "1.27.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" @@ -8410,6 +8690,16 @@ react-clientside-effect@^1.2.6: dependencies: "@babel/runtime" "^7.12.13" +react-code-blocks@^0.0.9-0: + version "0.0.9-0" + resolved "https://registry.yarnpkg.com/react-code-blocks/-/react-code-blocks-0.0.9-0.tgz#0c6d04d8a40b74cffe95f24f1a8e62a0fda8c014" + integrity sha512-jdYJVZwGtsr6WIUaqILy5fkF1acf57YV5s0V3+w5o9v3omYnqBeO6EuZi1Vf2x1hahkYGEedsp46+ofdkYlqyw== + dependencies: + "@babel/runtime" "^7.10.4" + react-syntax-highlighter "^12.2.1" + styled-components "^5.1.1" + tslib "^2.0.0" + react-dev-utils@^12.0.1: version "12.0.1" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz#ba92edb4a1f379bd46ccd6bcd4e7bc398df33e73" @@ -8643,6 +8933,17 @@ react-style-singleton@^2.2.0: invariant "^2.2.4" tslib "^2.0.0" +react-syntax-highlighter@^12.2.1: + version "12.2.1" + resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-12.2.1.tgz#14d78352da1c1c3f93c6698b70ec7c706b83493e" + integrity sha512-CTsp0ZWijwKRYFg9xhkWD4DSpQqE4vb2NKVMdPAkomnILSmsNBHE0n5GuI5zB+PU3ySVvXvdt9jo+ViD9XibCA== + dependencies: + "@babel/runtime" "^7.3.1" + highlight.js "~9.15.1" + lowlight "1.12.1" + prismjs "^1.8.4" + refractor "^2.4.1" + react-virtualized-auto-sizer@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.6.tgz#66c5b1c9278064c5ef1699ed40a29c11518f97ca" @@ -8715,6 +9016,15 @@ redux@^4.0.0, redux@^4.0.4: dependencies: "@babel/runtime" "^7.9.2" +refractor@^2.4.1: + version "2.10.1" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.10.1.tgz#166c32f114ed16fd96190ad21d5193d3afc7d34e" + integrity sha512-Xh9o7hQiQlDbxo5/XkOX6H+x/q8rmlmZKr97Ie1Q8ZM32IRRd3B/UxuA/yXDW79DBSXGWxm2yRTbcTVmAciJRw== + dependencies: + hastscript "^5.0.0" + parse-entities "^1.1.2" + prismjs "~1.17.0" + refractor@^3.5.0: version "3.6.0" resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.6.0.tgz#ac318f5a0715ead790fcfb0c71f4dd83d977935a" @@ -8736,6 +9046,11 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.9: version "0.13.9" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" @@ -9090,6 +9405,11 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= +select@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" + integrity sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA== + selfsigned@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" @@ -9185,6 +9505,11 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +shallowequal@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -9529,6 +9854,22 @@ style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" +styled-components@^5.1.1: + version "5.3.11" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.11.tgz#9fda7bf1108e39bf3f3e612fcc18170dedcd57a8" + integrity sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/traverse" "^7.4.5" + "@emotion/is-prop-valid" "^1.1.0" + "@emotion/stylis" "^0.8.4" + "@emotion/unitless" "^0.7.4" + babel-plugin-styled-components ">= 1.12.0" + css-to-react-native "^3.0.0" + hoist-non-react-statics "^3.0.0" + shallowequal "^1.1.0" + supports-color "^5.5.0" + stylehacks@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.0.tgz#a40066490ca0caca04e96c6b02153ddc39913520" @@ -9542,7 +9883,7 @@ stylis@4.0.13: resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91" integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag== -supports-color@^5.3.0: +supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -9733,6 +10074,11 @@ thunky@^1.0.2: resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== +tiny-emitter@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" + integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== + tiny-invariant@^1.0.6: version "1.2.0" resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9" diff --git a/ui/package.json b/ui/package.json index 298efeffab7..05579d5c88a 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "@feast-dev/feast-ui", - "version": "0.31.0", + "version": "0.32.0", "private": false, "files": [ "dist" From fb627d3e0041bca19a42eb8e9546fb3eae3abb24 Mon Sep 17 00:00:00 2001 From: Robin Neufeld Date: Mon, 24 Jul 2023 14:46:54 -0400 Subject: [PATCH 019/113] fix: Redshift push ignores schema (#3671) * Add fully-qualified-table-name Redshift prop Signed-off-by: Robin Neufeld * pre-commit Signed-off-by: Robin Neufeld * Docstring Signed-off-by: Robin Neufeld * Test fully_qualified_table_name Signed-off-by: Robin Neufeld * Simplify logic Signed-off-by: Robin Neufeld * pre-commit Signed-off-by: Robin Neufeld * pre-commit Signed-off-by: Robin Neufeld * Test offline_write_batch Signed-off-by: Robin Neufeld * Bump to trigger CI Signed-off-by: Robin Neufeld * another bump for ci Signed-off-by: Robin Neufeld --------- Signed-off-by: Robin Neufeld Signed-off-by: Attila Toth --- .../feast/infra/offline_stores/redshift.py | 2 +- .../infra/offline_stores/redshift_source.py | 37 +++++++++- .../infra/offline_stores/test_redshift.py | 67 +++++++++++++++++++ sdk/python/tests/unit/test_data_sources.py | 43 ++++++++++++ 4 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 sdk/python/tests/unit/infra/offline_stores/test_redshift.py diff --git a/sdk/python/feast/infra/offline_stores/redshift.py b/sdk/python/feast/infra/offline_stores/redshift.py index aba2bda353c..837cf49655d 100644 --- a/sdk/python/feast/infra/offline_stores/redshift.py +++ b/sdk/python/feast/infra/offline_stores/redshift.py @@ -369,7 +369,7 @@ def offline_write_batch( s3_resource=s3_resource, s3_path=f"{config.offline_store.s3_staging_location}/push/{uuid.uuid4()}.parquet", iam_role=config.offline_store.iam_role, - table_name=redshift_options.table, + table_name=redshift_options.fully_qualified_table_name, schema=pa_schema, fail_if_exists=False, ) diff --git a/sdk/python/feast/infra/offline_stores/redshift_source.py b/sdk/python/feast/infra/offline_stores/redshift_source.py index 1f80dede076..52ab50ba000 100644 --- a/sdk/python/feast/infra/offline_stores/redshift_source.py +++ b/sdk/python/feast/infra/offline_stores/redshift_source.py @@ -294,6 +294,42 @@ def from_proto(cls, redshift_options_proto: DataSourceProto.RedshiftOptions): return redshift_options + @property + def fully_qualified_table_name(self) -> str: + """ + The fully qualified table name of this Redshift table. + + Returns: + A string in the format of .. + May be empty or None if the table is not set + """ + + if not self.table: + return "" + + # self.table may already contain the database and schema + parts = self.table.split(".") + if len(parts) == 3: + database, schema, table = parts + elif len(parts) == 2: + database = self.database + schema, table = parts + elif len(parts) == 1: + database = self.database + schema = self.schema + table = parts[0] + else: + raise ValueError( + f"Invalid table name: {self.table} - can't determine database and schema" + ) + + if database and schema: + return f"{database}.{schema}.{table}" + elif schema: + return f"{schema}.{table}" + else: + return table + def to_proto(self) -> DataSourceProto.RedshiftOptions: """ Converts an RedshiftOptionsProto object to its protobuf representation. @@ -323,7 +359,6 @@ def __init__(self, table_ref: str): @staticmethod def from_proto(storage_proto: SavedDatasetStorageProto) -> SavedDatasetStorage: - return SavedDatasetRedshiftStorage( table_ref=RedshiftOptions.from_proto(storage_proto.redshift_storage).table ) diff --git a/sdk/python/tests/unit/infra/offline_stores/test_redshift.py b/sdk/python/tests/unit/infra/offline_stores/test_redshift.py new file mode 100644 index 00000000000..049977489b9 --- /dev/null +++ b/sdk/python/tests/unit/infra/offline_stores/test_redshift.py @@ -0,0 +1,67 @@ +from unittest.mock import MagicMock, patch + +import pandas as pd +import pyarrow as pa + +from feast import FeatureView +from feast.infra.offline_stores import offline_utils +from feast.infra.offline_stores.redshift import ( + RedshiftOfflineStore, + RedshiftOfflineStoreConfig, +) +from feast.infra.offline_stores.redshift_source import RedshiftSource +from feast.infra.utils import aws_utils +from feast.repo_config import RepoConfig + + +@patch.object(aws_utils, "upload_arrow_table_to_redshift") +def test_offline_write_batch( + mock_upload_arrow_table_to_redshift: MagicMock, + simple_dataset_1: pd.DataFrame, +): + repo_config = RepoConfig( + registry="registry", + project="project", + provider="local", + offline_store=RedshiftOfflineStoreConfig( + type="redshift", + region="us-west-2", + cluster_id="cluster_id", + database="database", + user="user", + iam_role="abcdef", + s3_staging_location="s3://bucket/path", + ), + ) + + batch_source = RedshiftSource( + name="test_source", + timestamp_field="ts", + table="table_name", + schema="schema_name", + ) + feature_view = FeatureView( + name="test_view", + source=batch_source, + ) + + pa_dataset = pa.Table.from_pandas(simple_dataset_1) + + # patch some more things so that the function can run + def mock_get_pyarrow_schema_from_batch_source(*args, **kwargs) -> pa.Schema: + return pa_dataset.schema, pa_dataset.column_names + + with patch.object( + offline_utils, + "get_pyarrow_schema_from_batch_source", + new=mock_get_pyarrow_schema_from_batch_source, + ): + RedshiftOfflineStore.offline_write_batch( + repo_config, feature_view, pa_dataset, progress=None + ) + + # check that we have included the fully qualified table name + mock_upload_arrow_table_to_redshift.assert_called_once() + + call = mock_upload_arrow_table_to_redshift.call_args_list[0] + assert call.kwargs["table_name"] == "schema_name.table_name" diff --git a/sdk/python/tests/unit/test_data_sources.py b/sdk/python/tests/unit/test_data_sources.py index 30b030feb67..990c5d3b698 100644 --- a/sdk/python/tests/unit/test_data_sources.py +++ b/sdk/python/tests/unit/test_data_sources.py @@ -190,3 +190,46 @@ def test_column_conflict(): timestamp_field="event_timestamp", created_timestamp_column="event_timestamp", ) + + +@pytest.mark.parametrize( + "source_kwargs,expected_name", + [ + ( + { + "database": "test_database", + "schema": "test_schema", + "table": "test_table", + }, + "test_database.test_schema.test_table", + ), + ( + {"database": "test_database", "table": "test_table"}, + "test_database.public.test_table", + ), + ({"table": "test_table"}, "public.test_table"), + ({"database": "test_database", "table": "b.c"}, "test_database.b.c"), + ({"database": "test_database", "table": "a.b.c"}, "a.b.c"), + ( + { + "database": "test_database", + "schema": "test_schema", + "query": "select * from abc", + }, + "", + ), + ], +) +def test_redshift_fully_qualified_table_name(source_kwargs, expected_name): + redshift_source = RedshiftSource( + name="test_source", + timestamp_field="event_timestamp", + created_timestamp_column="created_timestamp", + field_mapping={"foo": "bar"}, + description="test description", + tags={"test": "test"}, + owner="test@gmail.com", + **source_kwargs, + ) + + assert redshift_source.redshift_options.fully_qualified_table_name == expected_name From d6c6e73076405322c2d5731776c4cbff9a8edbe5 Mon Sep 17 00:00:00 2001 From: harmeet-singh-discovery <95894926+harmeet-singh-discovery@users.noreply.github.com> Date: Tue, 1 Aug 2023 13:35:03 -0700 Subject: [PATCH 020/113] fix: Add aws-sts dependency in java sdk so that S3 client acquires IRSA role (#3696) Add aws-sts dependency in java sdk Signed-off-by: harmeet-singh-discovery Signed-off-by: Attila Toth --- java/serving/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/java/serving/pom.xml b/java/serving/pom.xml index 8f0cf407e96..79f942d4918 100644 --- a/java/serving/pom.xml +++ b/java/serving/pom.xml @@ -243,6 +243,12 @@ 1.12.261 + + com.amazonaws + aws-java-sdk-sts + 1.12.476 + + com.adobe.testing s3mock-testcontainers From c37377ec34c1bf700ce6bcf9c3acfb907282d7cd Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Sun, 13 Aug 2023 18:23:50 -0700 Subject: [PATCH 021/113] Switch from `macos-10.15` to `macos-latest` (#3722) Signed-off-by: Felix Wang Signed-off-by: Attila Toth --- .github/workflows/build_wheels.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index 9bed2a4282b..38bd611e68f 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -79,7 +79,7 @@ jobs: build-source-distribution: name: Build source distribution - runs-on: macos-10.15 + runs-on: macos-latest steps: - uses: actions/checkout@v2 - name: Setup Python @@ -136,7 +136,7 @@ jobs: needs: [build-python-wheel, build-source-distribution, get-version] strategy: matrix: - os: [ubuntu-latest, macos-10.15 ] + os: [ubuntu-latest, macos-latest ] python-version: [ "3.8", "3.9", "3.10"] from-source: [ True, False ] env: @@ -165,7 +165,7 @@ jobs: name: wheels path: dist - name: Install OS X dependencies - if: matrix.os == 'macos-10.15' + if: matrix.os == 'macos-latest' run: brew install coreutils - name: Install wheel if: ${{ !matrix.from-source }} From ece2754c6a899c473034f6292cfe90ade1ad9e7d Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Sun, 13 Aug 2023 18:44:45 -0700 Subject: [PATCH 022/113] ci: Upgrade `checkout` Github Action (#3723) * Switch from `macos-10.15` to `macos-latest` Signed-off-by: Felix Wang * ci: Upgrade from `actions/checkout@v2` to `actions/checkout@v3` Signed-off-by: Felix Wang --------- Signed-off-by: Felix Wang Signed-off-by: Attila Toth --- .github/fork_workflows/fork_pr_integration_tests_aws.yml | 2 +- .github/fork_workflows/fork_pr_integration_tests_gcp.yml | 2 +- .../fork_pr_integration_tests_snowflake.yml | 2 +- .github/workflows/build_wheels.yml | 8 ++++---- .github/workflows/java_master_only.yml | 8 ++++---- .github/workflows/java_pr.yml | 8 ++++---- .github/workflows/linter.yml | 2 +- .github/workflows/master_only.yml | 6 +++--- .github/workflows/nightly-ci.yml | 6 +++--- .github/workflows/pr_integration_tests.yml | 2 +- .github/workflows/pr_local_integration_tests.yml | 2 +- .github/workflows/publish.yml | 8 ++++---- .github/workflows/release.yml | 8 ++++---- .github/workflows/unit_tests.yml | 4 ++-- 14 files changed, 34 insertions(+), 34 deletions(-) diff --git a/.github/fork_workflows/fork_pr_integration_tests_aws.yml b/.github/fork_workflows/fork_pr_integration_tests_aws.yml index e4362af7d3e..899c5528e67 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_aws.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_aws.yml @@ -83,7 +83,7 @@ jobs: --health-timeout 5s --health-retries 5 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: # pull_request_target runs the workflow in the context of the base repo # as such actions/checkout needs to be explicit configured to retrieve diff --git a/.github/fork_workflows/fork_pr_integration_tests_gcp.yml b/.github/fork_workflows/fork_pr_integration_tests_gcp.yml index d77c1052e7c..7aee4f8caae 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_gcp.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_gcp.yml @@ -25,7 +25,7 @@ jobs: --health-timeout 5s --health-retries 5 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: # pull_request_target runs the workflow in the context of the base repo # as such actions/checkout needs to be explicit configured to retrieve diff --git a/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml b/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml index 56b4c268b70..ddb969548d7 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml @@ -25,7 +25,7 @@ jobs: --health-timeout 5s --health-retries 5 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: # pull_request_target runs the workflow in the context of the base repo # as such actions/checkout needs to be explicit configured to retrieve diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index 38bd611e68f..cb08c5bc431 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -18,7 +18,7 @@ jobs: highest_semver_tag: ${{ steps.get_highest_semver.outputs.highest_semver_tag }} steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: persist-credentials: false - name: Get release version @@ -55,7 +55,7 @@ jobs: name: Build wheels runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Python uses: actions/setup-python@v2 with: @@ -81,7 +81,7 @@ jobs: name: Build source distribution runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Python id: setup-python uses: actions/setup-python@v2 @@ -120,7 +120,7 @@ jobs: env: REGISTRY: feastdev steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up QEMU uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx diff --git a/.github/workflows/java_master_only.yml b/.github/workflows/java_master_only.yml index f4c280d682d..70daa6a5b69 100644 --- a/.github/workflows/java_master_only.yml +++ b/.github/workflows/java_master_only.yml @@ -18,7 +18,7 @@ jobs: MAVEN_CACHE: gs://feast-templocation-kf-feast/.m2.2020-08-19.tar REGISTRY: gcr.io/kf-feast steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: 'true' - name: Setup Python @@ -53,7 +53,7 @@ jobs: if: github.repository == 'feast-dev/feast' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: 'true' - name: Lint java @@ -63,7 +63,7 @@ jobs: if: github.repository == 'feast-dev/feast' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: 'true' - name: Set up JDK 11 @@ -97,7 +97,7 @@ jobs: env: PYTHON: 3.8 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: 'true' - name: Set up JDK 11 diff --git a/.github/workflows/java_pr.yml b/.github/workflows/java_pr.yml index ad8700c0722..c7b993862c1 100644 --- a/.github/workflows/java_pr.yml +++ b/.github/workflows/java_pr.yml @@ -12,7 +12,7 @@ jobs: if: github.repository == 'feast-dev/feast' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: # pull_request_target runs the workflow in the context of the base repo # as such actions/checkout needs to be explicit configured to retrieve @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest needs: lint-java steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: # pull_request_target runs the workflow in the context of the base repo # as such actions/checkout needs to be explicit configured to retrieve @@ -69,7 +69,7 @@ jobs: MAVEN_CACHE: gs://feast-templocation-kf-feast/.m2.2020-08-19.tar REGISTRY: gcr.io/kf-feast steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: 'true' - name: Setup Python @@ -101,7 +101,7 @@ jobs: env: PYTHON: 3.8 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: # pull_request_target runs the workflow in the context of the base repo # as such actions/checkout needs to be explicit configured to retrieve diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 31657d3dfcb..d26d490260d 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -8,7 +8,7 @@ jobs: env: PYTHON: 3.8 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Python id: setup-python uses: actions/setup-python@v2 diff --git a/.github/workflows/master_only.yml b/.github/workflows/master_only.yml index 49d6fa4f856..f81f3cf1903 100644 --- a/.github/workflows/master_only.yml +++ b/.github/workflows/master_only.yml @@ -10,7 +10,7 @@ jobs: if: github.repository == 'feast-dev/feast' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up QEMU uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx @@ -81,7 +81,7 @@ jobs: --health-timeout 5s --health-retries 5 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Python id: setup-python uses: actions/setup-python@v2 @@ -166,7 +166,7 @@ jobs: MAVEN_CACHE: gs://feast-templocation-kf-feast/.m2.2020-08-19.tar REGISTRY: gcr.io/kf-feast steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up QEMU uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx diff --git a/.github/workflows/nightly-ci.yml b/.github/workflows/nightly-ci.yml index a0d1052fdb6..40bd26238e7 100644 --- a/.github/workflows/nightly-ci.yml +++ b/.github/workflows/nightly-ci.yml @@ -17,7 +17,7 @@ jobs: outputs: WAS_EDITED: ${{ steps.check_date.outputs.WAS_EDITED }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: ref: master - id: check_date @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest name: Cleanup Bigtable / Dynamo tables which can fail to cleanup steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: ref: master - name: Setup Python @@ -140,7 +140,7 @@ jobs: --health-timeout 5s --health-retries 5 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: ref: master submodules: recursive diff --git a/.github/workflows/pr_integration_tests.yml b/.github/workflows/pr_integration_tests.yml index 1fd49f08aff..b5d555cd287 100644 --- a/.github/workflows/pr_integration_tests.yml +++ b/.github/workflows/pr_integration_tests.yml @@ -102,7 +102,7 @@ jobs: --health-timeout 5s --health-retries 5 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: # pull_request_target runs the workflow in the context of the base repo # as such actions/checkout needs to be explicit configured to retrieve diff --git a/.github/workflows/pr_local_integration_tests.yml b/.github/workflows/pr_local_integration_tests.yml index 41df3aefff2..89fe49e261c 100644 --- a/.github/workflows/pr_local_integration_tests.yml +++ b/.github/workflows/pr_local_integration_tests.yml @@ -25,7 +25,7 @@ jobs: OS: ${{ matrix.os }} PYTHON: ${{ matrix.python-version }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: # pull_request_target runs the workflow in the context of the base repo # as such actions/checkout needs to be explicit configured to retrieve diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 11f08bf2e52..93ced3a6c81 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,7 +14,7 @@ jobs: version_without_prefix: ${{ steps.get_release_version_without_prefix.outputs.version_without_prefix }} highest_semver_tag: ${{ steps.get_highest_semver.outputs.highest_semver_tag }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Get release version id: get_release_version run: echo ::set-output name=release_version::${GITHUB_REF#refs/*/} @@ -54,7 +54,7 @@ jobs: MAVEN_CACHE: gs://feast-templocation-kf-feast/.m2.2020-08-19.tar REGISTRY: feastdev steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up QEMU uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx @@ -105,7 +105,7 @@ jobs: HELM_VERSION: v3.8.0 VERSION_WITHOUT_PREFIX: ${{ needs.get-version.outputs.version_without_prefix }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Authenticate to Google Cloud uses: 'google-github-actions/auth@v1' with: @@ -149,7 +149,7 @@ jobs: runs-on: ubuntu-latest needs: get-version steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: 'true' - name: Set up JDK 11 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index da16c5f8f1c..b2399f52db9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,7 +30,7 @@ jobs: next_version: ${{ steps.get_versions.outputs.next_version }} steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: persist-credentials: false - name: Setup Node.js @@ -59,7 +59,7 @@ jobs: CURRENT_VERSION: ${{ needs.get_dry_release_versions.outputs.current_version }} NEXT_VERSION: ${{ needs.get_dry_release_versions.outputs.next_version }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions/setup-node@v2 with: node-version: '18.x' @@ -100,7 +100,7 @@ jobs: CURRENT_VERSION: ${{ needs.get_dry_release_versions.outputs.current_version }} NEXT_VERSION: ${{ needs.get_dry_release_versions.outputs.next_version }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions/setup-node@v2 with: node-version: '18.x' @@ -133,7 +133,7 @@ jobs: GIT_COMMITTER_EMAIL: feast-ci-bot@willem.co steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: persist-credentials: false - name: Setup Node.js diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 285ebbb87e9..afad23846ab 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -18,7 +18,7 @@ jobs: OS: ${{ matrix.os }} PYTHON: ${{ matrix.python-version }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Python id: setup-python uses: actions/setup-python@v2 @@ -66,7 +66,7 @@ jobs: env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions/setup-node@v2 with: node-version: '17.x' From 111c7ae57c21a2ba3a21a8a9479ef1ef1c412ba3 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Sun, 13 Aug 2023 18:45:04 -0700 Subject: [PATCH 023/113] ci: Upgrade `setup-python` Github Action (#3724) * Switch from `macos-10.15` to `macos-latest` Signed-off-by: Felix Wang * ci: Upgrade `actions/setup-python@v2` to `actions/setup-python@v3` Signed-off-by: Felix Wang --------- Signed-off-by: Felix Wang Signed-off-by: Attila Toth --- .github/fork_workflows/fork_pr_integration_tests_aws.yml | 2 +- .github/fork_workflows/fork_pr_integration_tests_gcp.yml | 2 +- .../fork_workflows/fork_pr_integration_tests_snowflake.yml | 2 +- .github/workflows/build_wheels.yml | 6 +++--- .github/workflows/java_master_only.yml | 4 ++-- .github/workflows/java_pr.yml | 6 +++--- .github/workflows/linter.yml | 2 +- .github/workflows/master_only.yml | 2 +- .github/workflows/nightly-ci.yml | 4 ++-- .github/workflows/pr_integration_tests.yml | 2 +- .github/workflows/pr_local_integration_tests.yml | 2 +- .github/workflows/publish.yml | 2 +- .github/workflows/unit_tests.yml | 2 +- 13 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/fork_workflows/fork_pr_integration_tests_aws.yml b/.github/fork_workflows/fork_pr_integration_tests_aws.yml index 899c5528e67..c354dce970d 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_aws.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_aws.yml @@ -91,7 +91,7 @@ jobs: ref: refs/pull/${{ github.event.pull_request.number }}/merge submodules: recursive - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 id: setup-python with: python-version: ${{ matrix.python-version }} diff --git a/.github/fork_workflows/fork_pr_integration_tests_gcp.yml b/.github/fork_workflows/fork_pr_integration_tests_gcp.yml index 7aee4f8caae..07eb323d567 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_gcp.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_gcp.yml @@ -33,7 +33,7 @@ jobs: ref: refs/pull/${{ github.event.pull_request.number }}/merge submodules: recursive - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 id: setup-python with: python-version: ${{ matrix.python-version }} diff --git a/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml b/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml index ddb969548d7..a86e9ad7a0a 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml @@ -33,7 +33,7 @@ jobs: ref: refs/pull/${{ github.event.pull_request.number }}/merge submodules: recursive - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 id: setup-python with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index cb08c5bc431..8c375b261b0 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -57,7 +57,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: python-version: "3.8" architecture: x64 @@ -84,7 +84,7 @@ jobs: - uses: actions/checkout@v3 - name: Setup Python id: setup-python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: python-version: "3.10" architecture: x64 @@ -156,7 +156,7 @@ jobs: steps: - name: Setup Python id: setup-python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: python-version: ${{ matrix.python-version }} architecture: x64 diff --git a/.github/workflows/java_master_only.yml b/.github/workflows/java_master_only.yml index 70daa6a5b69..91656ad271b 100644 --- a/.github/workflows/java_master_only.yml +++ b/.github/workflows/java_master_only.yml @@ -22,7 +22,7 @@ jobs: with: submodules: 'true' - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 id: setup-python with: python-version: "3.8" @@ -107,7 +107,7 @@ jobs: java-package: jdk architecture: x64 - name: Setup Python (to call feast apply) - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 id: setup-python with: python-version: 3.8 diff --git a/.github/workflows/java_pr.yml b/.github/workflows/java_pr.yml index c7b993862c1..bf60d63ead6 100644 --- a/.github/workflows/java_pr.yml +++ b/.github/workflows/java_pr.yml @@ -73,7 +73,7 @@ jobs: with: submodules: 'true' - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 id: setup-python with: python-version: "3.8" @@ -114,7 +114,7 @@ jobs: java-version: '11' java-package: jdk architecture: x64 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v3 with: python-version: '3.8' architecture: 'x64' @@ -143,7 +143,7 @@ jobs: - name: Use AWS CLI run: aws sts get-caller-identity - name: Setup Python (to call feast apply) - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 id: setup-python with: python-version: 3.8 diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index d26d490260d..0f85cddf2dd 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v3 - name: Setup Python id: setup-python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: python-version: "3.8" architecture: x64 diff --git a/.github/workflows/master_only.yml b/.github/workflows/master_only.yml index f81f3cf1903..517095d7ece 100644 --- a/.github/workflows/master_only.yml +++ b/.github/workflows/master_only.yml @@ -84,7 +84,7 @@ jobs: - uses: actions/checkout@v3 - name: Setup Python id: setup-python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: python-version: ${{ matrix.python-version }} architecture: x64 diff --git a/.github/workflows/nightly-ci.yml b/.github/workflows/nightly-ci.yml index 40bd26238e7..fd5bc9f85f4 100644 --- a/.github/workflows/nightly-ci.yml +++ b/.github/workflows/nightly-ci.yml @@ -33,7 +33,7 @@ jobs: with: ref: master - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 id: setup-python with: python-version: "3.8" @@ -145,7 +145,7 @@ jobs: ref: master submodules: recursive - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 id: setup-python with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/pr_integration_tests.yml b/.github/workflows/pr_integration_tests.yml index b5d555cd287..6b19b2f6300 100644 --- a/.github/workflows/pr_integration_tests.yml +++ b/.github/workflows/pr_integration_tests.yml @@ -110,7 +110,7 @@ jobs: ref: refs/pull/${{ github.event.pull_request.number }}/merge submodules: recursive - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 id: setup-python with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/pr_local_integration_tests.yml b/.github/workflows/pr_local_integration_tests.yml index 89fe49e261c..527d279f10a 100644 --- a/.github/workflows/pr_local_integration_tests.yml +++ b/.github/workflows/pr_local_integration_tests.yml @@ -33,7 +33,7 @@ jobs: ref: refs/pull/${{ github.event.pull_request.number }}/merge submodules: recursive - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 id: setup-python with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 93ced3a6c81..135d1d3a8df 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -158,7 +158,7 @@ jobs: java-version: '11' java-package: jdk architecture: x64 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v3 with: python-version: '3.7' architecture: 'x64' diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index afad23846ab..bee69472f5e 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v3 - name: Setup Python id: setup-python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: python-version: ${{ matrix.python-version }} architecture: x64 From 14b7eb788b6ec0af5276c9397396c043e8ca3f95 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Sun, 13 Aug 2023 18:48:18 -0700 Subject: [PATCH 024/113] ci: Upgrade `setup-node` Github Action (#3725) Upgrade `actions/setup-node@v2` to `actions/setup-node@v3` Signed-off-by: Felix Wang Signed-off-by: Attila Toth --- .github/workflows/build_wheels.yml | 4 ++-- .github/workflows/release.yml | 8 ++++---- .github/workflows/unit_tests.yml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index 8c375b261b0..acbb5fd377d 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -62,7 +62,7 @@ jobs: python-version: "3.8" architecture: x64 - name: Setup Node - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: '17.x' registry-url: 'https://registry.npmjs.org' @@ -89,7 +89,7 @@ jobs: python-version: "3.10" architecture: x64 - name: Setup Node - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: '17.x' registry-url: 'https://registry.npmjs.org' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b2399f52db9..a01bae40687 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,7 +34,7 @@ jobs: with: persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: '18.x' registry-url: 'https://registry.npmjs.org' @@ -60,7 +60,7 @@ jobs: NEXT_VERSION: ${{ needs.get_dry_release_versions.outputs.next_version }} steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: '18.x' registry-url: 'https://registry.npmjs.org' @@ -101,7 +101,7 @@ jobs: NEXT_VERSION: ${{ needs.get_dry_release_versions.outputs.next_version }} steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: '18.x' registry-url: 'https://registry.npmjs.org' @@ -137,7 +137,7 @@ jobs: with: persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: '18.x' registry-url: 'https://registry.npmjs.org' diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index bee69472f5e..37457250223 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -67,7 +67,7 @@ jobs: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: '17.x' registry-url: 'https://registry.npmjs.org' From 4eb080b0af44261819c32640e8f5122d36498b08 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Sun, 13 Aug 2023 18:48:30 -0700 Subject: [PATCH 025/113] ci: Upgrade `upload-artifact` Github Action (#3726) * Switch from `macos-10.15` to `macos-latest` Signed-off-by: Felix Wang * Upgrade `actions/upload-artifact@v2` to `actions/upload-artifact@v3` Signed-off-by: Felix Wang --------- Signed-off-by: Felix Wang Signed-off-by: Attila Toth --- .github/workflows/build_wheels.yml | 4 ++-- .github/workflows/java_master_only.yml | 2 +- .github/workflows/java_pr.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index acbb5fd377d..a34be284d5c 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -72,7 +72,7 @@ jobs: run: | python -m pip install build python -m build --wheel --outdir wheelhouse/ - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: wheels path: ./wheelhouse/*.whl @@ -105,7 +105,7 @@ jobs: - name: Build run: | python3 setup.py sdist - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: wheels path: dist/* diff --git a/.github/workflows/java_master_only.yml b/.github/workflows/java_master_only.yml index 91656ad271b..00d8e628c97 100644 --- a/.github/workflows/java_master_only.yml +++ b/.github/workflows/java_master_only.yml @@ -86,7 +86,7 @@ jobs: ${{ runner.os }}-ut-maven- - name: Test java run: make test-java-with-coverage - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: java-coverage-report path: ${{ github.workspace }}/docs/coverage/java/target/site/jacoco-aggregate/ diff --git a/.github/workflows/java_pr.yml b/.github/workflows/java_pr.yml index bf60d63ead6..152ca64cdb1 100644 --- a/.github/workflows/java_pr.yml +++ b/.github/workflows/java_pr.yml @@ -54,7 +54,7 @@ jobs: ${{ runner.os }}-ut-maven- - name: Test java run: make test-java-with-coverage - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: java-coverage-report path: ${{ github.workspace }}/docs/coverage/java/target/site/jacoco-aggregate/ @@ -172,7 +172,7 @@ jobs: - name: Run integration tests run: make test-java-integration - name: Save report - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: failure() with: name: it-report From 22b025456ec9f327d6d7c5d29118527395c3840f Mon Sep 17 00:00:00 2001 From: nsuraeva Date: Mon, 14 Aug 2023 05:24:47 +0300 Subject: [PATCH 026/113] feat: Add possibility to save dataset as table, when spark config has remote warehouse info (#3645) feat: add possibility to save dataset as table, when spark config has remote warehouse info Signed-off-by: nsuraeva Co-authored-by: nsuraeva Signed-off-by: Attila Toth --- .../contrib/spark_offline_store/spark.py | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark.py b/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark.py index 7574ac4865c..c9591b7c3f0 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark.py +++ b/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark.py @@ -352,13 +352,36 @@ def persist( ): """ Run the retrieval and persist the results in the same offline store used for read. - Please note the persisting is done only within the scope of the spark session. + Please note the persisting is done only within the scope of the spark session for local warehouse directory. """ assert isinstance(storage, SavedDatasetSparkStorage) table_name = storage.spark_options.table if not table_name: raise ValueError("Cannot persist, table_name is not defined") - self.to_spark_df().createOrReplaceTempView(table_name) + if self._has_remote_warehouse_in_config(): + file_format = storage.spark_options.file_format + if not file_format: + self.to_spark_df().write.saveAsTable(table_name) + else: + self.to_spark_df().write.format(file_format).saveAsTable(table_name) + else: + self.to_spark_df().createOrReplaceTempView(table_name) + + def _has_remote_warehouse_in_config(self) -> bool: + """ + Check if Spark Session config has info about hive metastore uri + or warehouse directory is not a local path + """ + self.spark_session.sparkContext.getConf().getAll() + try: + self.spark_session.conf.get("hive.metastore.uris") + return True + except Exception: + warehouse_dir = self.spark_session.conf.get("spark.sql.warehouse.dir") + if warehouse_dir and warehouse_dir.startswith("file:"): + return False + else: + return True def supports_remote_storage_export(self) -> bool: return self._config.offline_store.staging_location is not None From 731bea8337417a3208882bab4e5ee5abf4366c3b Mon Sep 17 00:00:00 2001 From: feast-ci-bot Date: Mon, 14 Aug 2023 02:44:18 +0000 Subject: [PATCH 027/113] chore(release): release 0.33.0 # [0.33.0](https://github.com/feast-dev/feast/compare/v0.32.0...v0.33.0) (2023-08-14) ### Bug Fixes * Add aws-sts dependency in java sdk so that S3 client acquires IRSA role ([#3696](https://github.com/feast-dev/feast/issues/3696)) ([c75a01f](https://github.com/feast-dev/feast/commit/c75a01fce2d52cd18479ace748b8eb2e6c81c988)) * Redshift push ignores schema ([#3671](https://github.com/feast-dev/feast/issues/3671)) ([76270f6](https://github.com/feast-dev/feast/commit/76270f66b3d98b0119b70927c06908f9834b6120)) ### Features * Add possibility to save dataset as table, when spark config has remote warehouse info ([#3645](https://github.com/feast-dev/feast/issues/3645)) ([22c109b](https://github.com/feast-dev/feast/commit/22c109bc088d093a7c81c59e11490a9a21f82309)) Signed-off-by: Attila Toth --- CHANGELOG.md | 13 +++++++++++++ infra/charts/feast-feature-server/Chart.yaml | 2 +- infra/charts/feast-feature-server/README.md | 4 ++-- infra/charts/feast-feature-server/values.yaml | 2 +- infra/charts/feast/Chart.yaml | 2 +- infra/charts/feast/README.md | 6 +++--- infra/charts/feast/charts/feature-server/Chart.yaml | 4 ++-- infra/charts/feast/charts/feature-server/README.md | 4 ++-- .../charts/feast/charts/feature-server/values.yaml | 2 +- .../feast/charts/transformation-service/Chart.yaml | 4 ++-- .../feast/charts/transformation-service/README.md | 4 ++-- .../feast/charts/transformation-service/values.yaml | 2 +- infra/charts/feast/requirements.yaml | 4 ++-- java/pom.xml | 2 +- sdk/python/feast/ui/package.json | 2 +- sdk/python/feast/ui/yarn.lock | 8 ++++---- ui/package.json | 2 +- 17 files changed, 40 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f21ecd9ff8d..585be439bac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +# [0.33.0](https://github.com/feast-dev/feast/compare/v0.32.0...v0.33.0) (2023-08-14) + + +### Bug Fixes + +* Add aws-sts dependency in java sdk so that S3 client acquires IRSA role ([#3696](https://github.com/feast-dev/feast/issues/3696)) ([c75a01f](https://github.com/feast-dev/feast/commit/c75a01fce2d52cd18479ace748b8eb2e6c81c988)) +* Redshift push ignores schema ([#3671](https://github.com/feast-dev/feast/issues/3671)) ([76270f6](https://github.com/feast-dev/feast/commit/76270f66b3d98b0119b70927c06908f9834b6120)) + + +### Features + +* Add possibility to save dataset as table, when spark config has remote warehouse info ([#3645](https://github.com/feast-dev/feast/issues/3645)) ([22c109b](https://github.com/feast-dev/feast/commit/22c109bc088d093a7c81c59e11490a9a21f82309)) + # [0.32.0](https://github.com/feast-dev/feast/compare/v0.31.0...v0.32.0) (2023-07-17) diff --git a/infra/charts/feast-feature-server/Chart.yaml b/infra/charts/feast-feature-server/Chart.yaml index e55bd86b544..3ab493fc5fb 100644 --- a/infra/charts/feast-feature-server/Chart.yaml +++ b/infra/charts/feast-feature-server/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: feast-feature-server description: Feast Feature Server in Go or Python type: application -version: 0.32.0 +version: 0.33.0 keywords: - machine learning - big data diff --git a/infra/charts/feast-feature-server/README.md b/infra/charts/feast-feature-server/README.md index 00ae16b0cd1..e175f78510a 100644 --- a/infra/charts/feast-feature-server/README.md +++ b/infra/charts/feast-feature-server/README.md @@ -1,6 +1,6 @@ # Feast Python / Go Feature Server Helm Charts -Current chart version is `0.32.0` +Current chart version is `0.33.0` ## Installation @@ -30,7 +30,7 @@ See [here](https://github.com/feast-dev/feast/tree/master/examples/python-helm-d | fullnameOverride | string | `""` | | | image.pullPolicy | string | `"IfNotPresent"` | | | image.repository | string | `"feastdev/feature-server"` | Docker image for Feature Server repository | -| image.tag | string | `"0.32.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | +| image.tag | string | `"0.33.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | | imagePullSecrets | list | `[]` | | | livenessProbe.initialDelaySeconds | int | `30` | | | livenessProbe.periodSeconds | int | `30` | | diff --git a/infra/charts/feast-feature-server/values.yaml b/infra/charts/feast-feature-server/values.yaml index 68c35175c47..e9d09796a31 100644 --- a/infra/charts/feast-feature-server/values.yaml +++ b/infra/charts/feast-feature-server/values.yaml @@ -9,7 +9,7 @@ image: repository: feastdev/feature-server pullPolicy: IfNotPresent # image.tag -- The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) - tag: 0.32.0 + tag: 0.33.0 imagePullSecrets: [] nameOverride: "" diff --git a/infra/charts/feast/Chart.yaml b/infra/charts/feast/Chart.yaml index 5b7817bdcb4..b16165808f8 100644 --- a/infra/charts/feast/Chart.yaml +++ b/infra/charts/feast/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 description: Feature store for machine learning name: feast -version: 0.32.0 +version: 0.33.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index 777e036927d..846e8402361 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -8,7 +8,7 @@ This repo contains Helm charts for Feast Java components that are being installe ## Chart: Feast -Feature store for machine learning Current chart version is `0.32.0` +Feature store for machine learning Current chart version is `0.33.0` ## Installation @@ -65,8 +65,8 @@ See [here](https://github.com/feast-dev/feast/tree/master/examples/java-demo) fo | Repository | Name | Version | |------------|------|---------| | https://charts.helm.sh/stable | redis | 10.5.6 | -| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.32.0 | -| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.32.0 | +| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.33.0 | +| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.33.0 | ## Values diff --git a/infra/charts/feast/charts/feature-server/Chart.yaml b/infra/charts/feast/charts/feature-server/Chart.yaml index c4cd90a1e6b..931c34f7c94 100644 --- a/infra/charts/feast/charts/feature-server/Chart.yaml +++ b/infra/charts/feast/charts/feature-server/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 description: "Feast Feature Server: Online feature serving service for Feast" name: feature-server -version: 0.32.0 -appVersion: v0.32.0 +version: 0.33.0 +appVersion: v0.33.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/charts/feature-server/README.md b/infra/charts/feast/charts/feature-server/README.md index de4ff43e0dd..653b9dfb0c4 100644 --- a/infra/charts/feast/charts/feature-server/README.md +++ b/infra/charts/feast/charts/feature-server/README.md @@ -1,6 +1,6 @@ # feature-server -![Version: 0.32.0](https://img.shields.io/badge/Version-0.32.0-informational?style=flat-square) ![AppVersion: v0.32.0](https://img.shields.io/badge/AppVersion-v0.32.0-informational?style=flat-square) +![Version: 0.33.0](https://img.shields.io/badge/Version-0.33.0-informational?style=flat-square) ![AppVersion: v0.33.0](https://img.shields.io/badge/AppVersion-v0.33.0-informational?style=flat-square) Feast Feature Server: Online feature serving service for Feast @@ -17,7 +17,7 @@ Feast Feature Server: Online feature serving service for Feast | envOverrides | object | `{}` | Extra environment variables to set | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"feastdev/feature-server-java"` | Docker image for Feature Server repository | -| image.tag | string | `"0.32.0"` | Image tag | +| image.tag | string | `"0.33.0"` | Image tag | | ingress.grpc.annotations | object | `{}` | Extra annotations for the ingress | | ingress.grpc.auth.enabled | bool | `false` | Flag to enable auth | | ingress.grpc.class | string | `"nginx"` | Which ingress controller to use | diff --git a/infra/charts/feast/charts/feature-server/values.yaml b/infra/charts/feast/charts/feature-server/values.yaml index 5497aa74dc5..2403e796458 100644 --- a/infra/charts/feast/charts/feature-server/values.yaml +++ b/infra/charts/feast/charts/feature-server/values.yaml @@ -5,7 +5,7 @@ image: # image.repository -- Docker image for Feature Server repository repository: feastdev/feature-server-java # image.tag -- Image tag - tag: 0.32.0 + tag: 0.33.0 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/charts/transformation-service/Chart.yaml b/infra/charts/feast/charts/transformation-service/Chart.yaml index 7bda807cf17..7a4e0fd7d17 100644 --- a/infra/charts/feast/charts/transformation-service/Chart.yaml +++ b/infra/charts/feast/charts/transformation-service/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 description: "Transformation service: to compute on-demand features" name: transformation-service -version: 0.32.0 -appVersion: v0.32.0 +version: 0.33.0 +appVersion: v0.33.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/charts/transformation-service/README.md b/infra/charts/feast/charts/transformation-service/README.md index 121e24fe23f..0d217edf046 100644 --- a/infra/charts/feast/charts/transformation-service/README.md +++ b/infra/charts/feast/charts/transformation-service/README.md @@ -1,6 +1,6 @@ # transformation-service -![Version: 0.32.0](https://img.shields.io/badge/Version-0.32.0-informational?style=flat-square) ![AppVersion: v0.32.0](https://img.shields.io/badge/AppVersion-v0.32.0-informational?style=flat-square) +![Version: 0.33.0](https://img.shields.io/badge/Version-0.33.0-informational?style=flat-square) ![AppVersion: v0.33.0](https://img.shields.io/badge/AppVersion-v0.33.0-informational?style=flat-square) Transformation service: to compute on-demand features @@ -13,7 +13,7 @@ Transformation service: to compute on-demand features | envOverrides | object | `{}` | Extra environment variables to set | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"feastdev/feature-transformation-server"` | Docker image for Transformation Server repository | -| image.tag | string | `"0.32.0"` | Image tag | +| image.tag | string | `"0.33.0"` | Image tag | | nodeSelector | object | `{}` | Node labels for pod assignment | | podLabels | object | `{}` | Labels to be added to Feast Serving pods | | replicaCount | int | `1` | Number of pods that will be created | diff --git a/infra/charts/feast/charts/transformation-service/values.yaml b/infra/charts/feast/charts/transformation-service/values.yaml index f7acc7a1307..b7fdcb66590 100644 --- a/infra/charts/feast/charts/transformation-service/values.yaml +++ b/infra/charts/feast/charts/transformation-service/values.yaml @@ -5,7 +5,7 @@ image: # image.repository -- Docker image for Transformation Server repository repository: feastdev/feature-transformation-server # image.tag -- Image tag - tag: 0.32.0 + tag: 0.33.0 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/requirements.yaml b/infra/charts/feast/requirements.yaml index c04b3ee005b..5f855ef5278 100644 --- a/infra/charts/feast/requirements.yaml +++ b/infra/charts/feast/requirements.yaml @@ -1,12 +1,12 @@ dependencies: - name: feature-server alias: feature-server - version: 0.32.0 + version: 0.33.0 condition: feature-server.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: transformation-service alias: transformation-service - version: 0.32.0 + version: 0.33.0 condition: transformation-service.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: redis diff --git a/java/pom.xml b/java/pom.xml index beaa5fb07e6..0aa87a6feab 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -35,7 +35,7 @@ - 0.32.0 + 0.33.0 https://github.com/feast-dev/feast UTF-8 diff --git a/sdk/python/feast/ui/package.json b/sdk/python/feast/ui/package.json index 0b22aff8844..83722808820 100644 --- a/sdk/python/feast/ui/package.json +++ b/sdk/python/feast/ui/package.json @@ -6,7 +6,7 @@ "@elastic/datemath": "^5.0.3", "@elastic/eui": "^55.0.1", "@emotion/react": "^11.9.0", - "@feast-dev/feast-ui": "0.32.0", + "@feast-dev/feast-ui": "0.33.0", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.2.0", "@testing-library/user-event": "^13.5.0", diff --git a/sdk/python/feast/ui/yarn.lock b/sdk/python/feast/ui/yarn.lock index a61d5a1bbf6..28bfee06d1e 100644 --- a/sdk/python/feast/ui/yarn.lock +++ b/sdk/python/feast/ui/yarn.lock @@ -1452,10 +1452,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@feast-dev/feast-ui@0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@feast-dev/feast-ui/-/feast-ui-0.32.0.tgz#fb10bd4ead0eb4edcf9d7a7fc357f50c0b9ff656" - integrity sha512-RL3qpZRdsfxMqb/4HqbeFC3qik1gK5cPo+EmdAe8YXJ2IBy2OXXrekHxf1nmNlLQ29Ogg9VZ/LyAmwa8A3LR5w== +"@feast-dev/feast-ui@0.33.0": + version "0.33.0" + resolved "https://registry.yarnpkg.com/@feast-dev/feast-ui/-/feast-ui-0.33.0.tgz#4b8f8c5376103cac1ae0f25d6c9d359e4022707a" + integrity sha512-w+wa+YpFOIbxr4zTmGPuPITQhWfYIWjv7OmL7r/9yLbtQzp/6sKKChGYZwxi6pUu1ECsRc47uuSyhYllav3InQ== dependencies: "@elastic/datemath" "^5.0.3" "@elastic/eui" "^55.0.1" diff --git a/ui/package.json b/ui/package.json index 05579d5c88a..b81276d8257 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "@feast-dev/feast-ui", - "version": "0.32.0", + "version": "0.33.0", "private": false, "files": [ "dist" From 366fd33caabea57d8894d3942bbe78eccfeb8ee8 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Sun, 13 Aug 2023 20:23:03 -0700 Subject: [PATCH 028/113] ci: Temporarily disable smoke tests (#3727) Signed-off-by: Felix Wang Signed-off-by: Attila Toth --- .github/workflows/build_wheels.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index a34be284d5c..6e6539cf9e4 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -192,11 +192,12 @@ jobs: echo "$VERSION_OUTPUT from installed wheel is not in the correct format or doesn't have the right version $VERSION." exit 1 fi - - name: Smoke test - run: | - feast init test_repo - cd test_repo/feature_repo - feast apply - echo "$TEST_SCRIPT" > run-and-wait.sh - bash run-and-wait.sh feast serve - bash run-and-wait.sh feast ui + # This is temporarily disabled. + # - name: Smoke test + # run: | + # feast init test_repo + # cd test_repo/feature_repo + # feast apply + # echo "$TEST_SCRIPT" > run-and-wait.sh + # bash run-and-wait.sh feast serve + # bash run-and-wait.sh feast ui From db80a2b466af924015fe12bc533b3f2769187325 Mon Sep 17 00:00:00 2001 From: Shuchu Han Date: Sun, 13 Aug 2023 23:33:47 -0400 Subject: [PATCH 029/113] fix: Run store.plan() only when need it. (#3708) fix: issue-3682, run store.plan() only when need it. Signed-off-by: Attila Toth --- sdk/python/feast/repo_operations.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sdk/python/feast/repo_operations.py b/sdk/python/feast/repo_operations.py index 0cd425a46be..120f6e7a422 100644 --- a/sdk/python/feast/repo_operations.py +++ b/sdk/python/feast/repo_operations.py @@ -296,8 +296,6 @@ def apply_total_with_repo_instance( for data_source in data_sources: data_source.validate(store.config) - registry_diff, infra_diff, new_infra = store.plan(repo) - # For each object in the registry, determine whether it should be kept or deleted. ( all_to_apply, @@ -306,9 +304,10 @@ def apply_total_with_repo_instance( views_to_delete, ) = extract_objects_for_apply_delete(project, registry, repo) - click.echo(registry_diff.to_string()) - if store._should_use_plan(): + registry_diff, infra_diff, new_infra = store.plan(repo) + click.echo(registry_diff.to_string()) + store._apply_diffs(registry_diff, infra_diff, new_infra) click.echo(infra_diff.to_string()) else: From f5d7f0443359756d6ac1b6c47d69088d650f5df0 Mon Sep 17 00:00:00 2001 From: crispin-ki <131684659+crispin-ki@users.noreply.github.com> Date: Wed, 16 Aug 2023 20:42:10 +0100 Subject: [PATCH 030/113] fix: Fix python unit tests (#3734) * Fix regex log_string_to_wait_for to be more generic for changing versions of mysql Signed-off-by: Crispin Logan * Add noqa otherwise flake incorrectly flags W605 Signed-off-by: Crispin Logan --------- Signed-off-by: Crispin Logan Signed-off-by: Attila Toth --- sdk/python/tests/unit/test_sql_registry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/tests/unit/test_sql_registry.py b/sdk/python/tests/unit/test_sql_registry.py index 1c2b5a36ddf..39896d3a9dd 100644 --- a/sdk/python/tests/unit/test_sql_registry.py +++ b/sdk/python/tests/unit/test_sql_registry.py @@ -91,7 +91,7 @@ def mysql_registry(): container.start() # The log string uses '8.0.*' since the version might be changed as new Docker images are pushed. - log_string_to_wait_for = "/usr/sbin/mysqld: ready for connections. Version: '8.0.*' socket: '/var/run/mysqld/mysqld.sock' port: 3306" + log_string_to_wait_for = "/usr/sbin/mysqld: ready for connections. Version: '(\d+(\.\d+){1,2})' socket: '/var/run/mysqld/mysqld.sock' port: 3306" # noqa: W605 waited = wait_for_logs( container=container, predicate=log_string_to_wait_for, From 20995a9c0a447d1940396b130db58c2b8672b6ac Mon Sep 17 00:00:00 2001 From: crispin-ki <131684659+crispin-ki@users.noreply.github.com> Date: Mon, 28 Aug 2023 06:26:49 +0100 Subject: [PATCH 031/113] fix: Update py3.8 ci requirements for cython 3.0 release (#3735) * Update py3.8 ci reqs due to cython 3.0 release Signed-off-by: Crispin Logan * Update py3.9 ci reqs due to cython 3.0 release Signed-off-by: Crispin Logan * Update py3.10 ci reqs due to cython 3.0 release Signed-off-by: Crispin Logan * Update py3.8 reqs due to cython 3.0 release Signed-off-by: Crispin Logan * Update py3.9 reqs due to cython 3.0 release Signed-off-by: Crispin Logan * Update py3.10 reqs due to cython 3.0 release Signed-off-by: Crispin Logan --------- Signed-off-by: Crispin Logan Signed-off-by: Attila Toth --- sdk/python/requirements/py3.10-ci-requirements.txt | 6 +++--- sdk/python/requirements/py3.10-requirements.txt | 4 ++-- sdk/python/requirements/py3.8-ci-requirements.txt | 6 +++--- sdk/python/requirements/py3.8-requirements.txt | 4 ++-- sdk/python/requirements/py3.9-ci-requirements.txt | 6 +++--- sdk/python/requirements/py3.9-requirements.txt | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index 6586bdef335..2f28a271dc3 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -206,7 +206,7 @@ executing==1.2.0 # via stack-data fastapi==0.95.2 # via feast (setup.py) -fastavro==1.7.4 +fastavro==1.8.1 # via # feast (setup.py) # pandavro @@ -702,7 +702,7 @@ pyjwt[crypto]==2.7.0 # adal # msal # snowflake-connector-python -pymssql==2.2.7 +pymssql==2.2.8 # via feast (setup.py) pymysql==1.0.3 # via feast (setup.py) @@ -767,7 +767,7 @@ pytz==2023.3 # pandas # snowflake-connector-python # trino -pyyaml==6.0 +pyyaml==6.0.1 # via # dask # feast (setup.py) diff --git a/sdk/python/requirements/py3.10-requirements.txt b/sdk/python/requirements/py3.10-requirements.txt index 3eab83fe48c..d9b70d51974 100644 --- a/sdk/python/requirements/py3.10-requirements.txt +++ b/sdk/python/requirements/py3.10-requirements.txt @@ -43,7 +43,7 @@ exceptiongroup==1.1.1 # via anyio fastapi==0.95.2 # via feast (setup.py) -fastavro==1.7.4 +fastavro==1.8.1 # via # feast (setup.py) # pandavro @@ -133,7 +133,7 @@ python-dotenv==1.0.0 # via uvicorn pytz==2023.3 # via pandas -pyyaml==6.0 +pyyaml==6.0.1 # via # dask # feast (setup.py) diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index 85e089b03a9..de814374b68 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -210,7 +210,7 @@ executing==1.2.0 # via stack-data fastapi==0.95.2 # via feast (setup.py) -fastavro==1.7.4 +fastavro==1.8.1 # via # feast (setup.py) # pandavro @@ -713,7 +713,7 @@ pyjwt[crypto]==2.7.0 # adal # msal # snowflake-connector-python -pymssql==2.2.7 +pymssql==2.2.8 # via feast (setup.py) pymysql==1.0.3 # via feast (setup.py) @@ -779,7 +779,7 @@ pytz==2023.3 # pandas # snowflake-connector-python # trino -pyyaml==6.0 +pyyaml==6.0.1 # via # dask # feast (setup.py) diff --git a/sdk/python/requirements/py3.8-requirements.txt b/sdk/python/requirements/py3.8-requirements.txt index b374356b24d..55ee6349048 100644 --- a/sdk/python/requirements/py3.8-requirements.txt +++ b/sdk/python/requirements/py3.8-requirements.txt @@ -43,7 +43,7 @@ exceptiongroup==1.1.1 # via anyio fastapi==0.95.2 # via feast (setup.py) -fastavro==1.7.4 +fastavro==1.8.1 # via # feast (setup.py) # pandavro @@ -137,7 +137,7 @@ python-dotenv==1.0.0 # via uvicorn pytz==2023.3 # via pandas -pyyaml==6.0 +pyyaml==6.0.1 # via # dask # feast (setup.py) diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index 55a283fb245..aa79b8ec3be 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -206,7 +206,7 @@ executing==1.2.0 # via stack-data fastapi==0.95.2 # via feast (setup.py) -fastavro==1.7.4 +fastavro==1.8.1 # via # feast (setup.py) # pandavro @@ -705,7 +705,7 @@ pyjwt[crypto]==2.7.0 # adal # msal # snowflake-connector-python -pymssql==2.2.7 +pymssql==2.2.8 # via feast (setup.py) pymysql==1.0.3 # via feast (setup.py) @@ -770,7 +770,7 @@ pytz==2023.3 # pandas # snowflake-connector-python # trino -pyyaml==6.0 +pyyaml==6.0.1 # via # dask # feast (setup.py) diff --git a/sdk/python/requirements/py3.9-requirements.txt b/sdk/python/requirements/py3.9-requirements.txt index a96864ef531..53b0ff0e584 100644 --- a/sdk/python/requirements/py3.9-requirements.txt +++ b/sdk/python/requirements/py3.9-requirements.txt @@ -43,7 +43,7 @@ exceptiongroup==1.1.1 # via anyio fastapi==0.95.2 # via feast (setup.py) -fastavro==1.7.4 +fastavro==1.8.1 # via # feast (setup.py) # pandavro @@ -133,7 +133,7 @@ python-dotenv==1.0.0 # via uvicorn pytz==2023.3 # via pandas -pyyaml==6.0 +pyyaml==6.0.1 # via # dask # feast (setup.py) From 23c66837ac906f2eaf22bb940d5a4d11ae1d38d4 Mon Sep 17 00:00:00 2001 From: Danny C Date: Sun, 27 Aug 2023 22:29:14 -0700 Subject: [PATCH 032/113] fix: Pin protobuf version to avoid seg fault on some machines Signed-off-by: Danny C Signed-off-by: Attila Toth --- Makefile | 2 +- setup.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a104bf9ca5a..cf8a899ac68 100644 --- a/Makefile +++ b/Makefile @@ -353,7 +353,7 @@ kill-trino-locally: cd ${ROOT_DIR}; docker stop trino install-protoc-dependencies: - pip install --ignore-installed protobuf grpcio-tools==1.47.0 mypy-protobuf==3.1.0 + pip install --ignore-installed protobuf==4.23.4 grpcio-tools==1.47.0 mypy-protobuf==3.1.0 install-feast-ci-locally: pip install -e ".[ci]" diff --git a/setup.py b/setup.py index aee2ed0b3eb..f10322ed8a3 100644 --- a/setup.py +++ b/setup.py @@ -55,7 +55,8 @@ "pandas>=1.4.3,<2", # For some reason pandavro higher than 1.5.* only support pandas less than 1.3. "pandavro~=1.5.0", - "protobuf<5,>3.20", + # Higher than 4.23.4 seems to cause a seg fault + "protobuf<4.23.4,>3.20", "proto-plus>=1.20.0,<2", "pyarrow>=4,<12", "pydantic>=1,<2", From 2cc2e5ac11caf83efef5dfd420fdc422548760f0 Mon Sep 17 00:00:00 2001 From: Danny C Date: Sun, 27 Aug 2023 23:19:38 -0700 Subject: [PATCH 033/113] ci: Pin pip version to avoid test breakage Signed-off-by: Danny C Signed-off-by: Attila Toth --- .github/workflows/java_master_only.yml | 2 +- .github/workflows/java_pr.yml | 2 +- .github/workflows/linter.yml | 2 +- .github/workflows/master_only.yml | 2 +- .github/workflows/nightly-ci.yml | 2 +- .github/workflows/pr_integration_tests.yml | 2 +- .github/workflows/pr_local_integration_tests.yml | 2 +- .github/workflows/unit_tests.yml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/java_master_only.yml b/.github/workflows/java_master_only.yml index 00d8e628c97..23a12259cad 100644 --- a/.github/workflows/java_master_only.yml +++ b/.github/workflows/java_master_only.yml @@ -114,7 +114,7 @@ jobs: architecture: x64 - name: Upgrade pip version run: | - pip install --upgrade pip + pip install --upgrade "pip>=21.3.1,<22.1" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/java_pr.yml b/.github/workflows/java_pr.yml index 152ca64cdb1..03aa6d63cd5 100644 --- a/.github/workflows/java_pr.yml +++ b/.github/workflows/java_pr.yml @@ -150,7 +150,7 @@ jobs: architecture: x64 - name: Upgrade pip version run: | - pip install --upgrade pip + pip install --upgrade "pip>=21.3.1,<22.1" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 0f85cddf2dd..f033972917d 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -17,7 +17,7 @@ jobs: architecture: x64 - name: Upgrade pip version run: | - pip install --upgrade pip + pip install --upgrade "pip>=21.3.1,<22.1" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/master_only.yml b/.github/workflows/master_only.yml index 517095d7ece..4ec109a39ff 100644 --- a/.github/workflows/master_only.yml +++ b/.github/workflows/master_only.yml @@ -108,7 +108,7 @@ jobs: run: aws sts get-caller-identity - name: Upgrade pip version run: | - pip install --upgrade pip + pip install --upgrade "pip>=21.3.1,<22.1" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/nightly-ci.yml b/.github/workflows/nightly-ci.yml index fd5bc9f85f4..4ecd302c036 100644 --- a/.github/workflows/nightly-ci.yml +++ b/.github/workflows/nightly-ci.yml @@ -175,7 +175,7 @@ jobs: run: aws sts get-caller-identity - name: Upgrade pip version run: | - pip install --upgrade pip + pip install --upgrade "pip>=21.3.1,<22.1" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/pr_integration_tests.yml b/.github/workflows/pr_integration_tests.yml index 6b19b2f6300..47def1dcf9e 100644 --- a/.github/workflows/pr_integration_tests.yml +++ b/.github/workflows/pr_integration_tests.yml @@ -135,7 +135,7 @@ jobs: run: aws sts get-caller-identity - name: Upgrade pip version run: | - pip install --upgrade pip + pip install --upgrade "pip>=21.3.1,<22.1" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/pr_local_integration_tests.yml b/.github/workflows/pr_local_integration_tests.yml index 527d279f10a..db99cad63b0 100644 --- a/.github/workflows/pr_local_integration_tests.yml +++ b/.github/workflows/pr_local_integration_tests.yml @@ -40,7 +40,7 @@ jobs: architecture: x64 - name: Upgrade pip version run: | - pip install --upgrade pip + pip install --upgrade "pip>=21.3.1,<22.1" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 37457250223..992a3168c32 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -38,7 +38,7 @@ jobs: ln -sv $(brew --prefix zlib)/lib/libz.dylib $(brew --prefix)/lib/libzlib.dylib - name: Upgrade pip version run: | - pip install --upgrade pip + pip install --upgrade "pip>=21.3.1,<22.1" - name: Get pip cache dir id: pip-cache run: | From a7e5b336329319b20db89864fdaf8eafb9545850 Mon Sep 17 00:00:00 2001 From: Danny C Date: Sun, 27 Aug 2023 23:25:39 -0700 Subject: [PATCH 034/113] ci: Pin pip version to slightly higher to avoid test breakage Signed-off-by: Danny C Signed-off-by: Attila Toth --- .github/fork_workflows/fork_pr_integration_tests_aws.yml | 2 +- .github/fork_workflows/fork_pr_integration_tests_gcp.yml | 2 +- .github/fork_workflows/fork_pr_integration_tests_snowflake.yml | 2 +- .github/workflows/java_master_only.yml | 2 +- .github/workflows/java_pr.yml | 2 +- .github/workflows/linter.yml | 2 +- .github/workflows/master_only.yml | 2 +- .github/workflows/nightly-ci.yml | 2 +- .github/workflows/pr_integration_tests.yml | 2 +- .github/workflows/pr_local_integration_tests.yml | 2 +- .github/workflows/unit_tests.yml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/fork_workflows/fork_pr_integration_tests_aws.yml b/.github/fork_workflows/fork_pr_integration_tests_aws.yml index c354dce970d..ab5130c704e 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_aws.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_aws.yml @@ -111,7 +111,7 @@ jobs: run: aws sts get-caller-identity - name: Upgrade pip version run: | - pip install --upgrade "pip>=21.3.1,<22.1" + pip install --upgrade "pip>=21.3.1,<22.3" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/fork_workflows/fork_pr_integration_tests_gcp.yml b/.github/fork_workflows/fork_pr_integration_tests_gcp.yml index 07eb323d567..4b74c0ab096 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_gcp.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_gcp.yml @@ -55,7 +55,7 @@ jobs: run: gcloud info - name: Upgrade pip version run: | - pip install --upgrade "pip>=21.3.1,<22.1" + pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml b/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml index a86e9ad7a0a..cef970ab16a 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml @@ -46,7 +46,7 @@ jobs: - name: Upgrade pip version run: | - pip install --upgrade "pip>=21.3.1,<22.1" + pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/java_master_only.yml b/.github/workflows/java_master_only.yml index 23a12259cad..b15ddddc5d7 100644 --- a/.github/workflows/java_master_only.yml +++ b/.github/workflows/java_master_only.yml @@ -114,7 +114,7 @@ jobs: architecture: x64 - name: Upgrade pip version run: | - pip install --upgrade "pip>=21.3.1,<22.1" + pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/java_pr.yml b/.github/workflows/java_pr.yml index 03aa6d63cd5..a927587d7d3 100644 --- a/.github/workflows/java_pr.yml +++ b/.github/workflows/java_pr.yml @@ -150,7 +150,7 @@ jobs: architecture: x64 - name: Upgrade pip version run: | - pip install --upgrade "pip>=21.3.1,<22.1" + pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index f033972917d..c2112ea303f 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -17,7 +17,7 @@ jobs: architecture: x64 - name: Upgrade pip version run: | - pip install --upgrade "pip>=21.3.1,<22.1" + pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/master_only.yml b/.github/workflows/master_only.yml index 4ec109a39ff..a7d412fd4ac 100644 --- a/.github/workflows/master_only.yml +++ b/.github/workflows/master_only.yml @@ -108,7 +108,7 @@ jobs: run: aws sts get-caller-identity - name: Upgrade pip version run: | - pip install --upgrade "pip>=21.3.1,<22.1" + pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/nightly-ci.yml b/.github/workflows/nightly-ci.yml index 4ecd302c036..03078c0a788 100644 --- a/.github/workflows/nightly-ci.yml +++ b/.github/workflows/nightly-ci.yml @@ -175,7 +175,7 @@ jobs: run: aws sts get-caller-identity - name: Upgrade pip version run: | - pip install --upgrade "pip>=21.3.1,<22.1" + pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/pr_integration_tests.yml b/.github/workflows/pr_integration_tests.yml index 47def1dcf9e..ed02636c993 100644 --- a/.github/workflows/pr_integration_tests.yml +++ b/.github/workflows/pr_integration_tests.yml @@ -135,7 +135,7 @@ jobs: run: aws sts get-caller-identity - name: Upgrade pip version run: | - pip install --upgrade "pip>=21.3.1,<22.1" + pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/pr_local_integration_tests.yml b/.github/workflows/pr_local_integration_tests.yml index db99cad63b0..1a2c0790d1a 100644 --- a/.github/workflows/pr_local_integration_tests.yml +++ b/.github/workflows/pr_local_integration_tests.yml @@ -40,7 +40,7 @@ jobs: architecture: x64 - name: Upgrade pip version run: | - pip install --upgrade "pip>=21.3.1,<22.1" + pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 992a3168c32..538a5819799 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -38,7 +38,7 @@ jobs: ln -sv $(brew --prefix zlib)/lib/libz.dylib $(brew --prefix)/lib/libzlib.dylib - name: Upgrade pip version run: | - pip install --upgrade "pip>=21.3.1,<22.1" + pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | From 67a3f77db10ded89db5853ebd2fdb184dd6a18b9 Mon Sep 17 00:00:00 2001 From: Danny C Date: Mon, 4 Sep 2023 18:56:20 -0700 Subject: [PATCH 035/113] ci: Fix ci breakage from old pip version being restored from pip cache Signed-off-by: Danny C Signed-off-by: Attila Toth --- .github/fork_workflows/fork_pr_integration_tests_aws.yml | 6 +++--- .github/fork_workflows/fork_pr_integration_tests_gcp.yml | 6 +++--- .../fork_workflows/fork_pr_integration_tests_snowflake.yml | 7 +++---- .github/workflows/java_master_only.yml | 7 +++---- .github/workflows/java_pr.yml | 6 +++--- .github/workflows/linter.yml | 6 +++--- .github/workflows/master_only.yml | 6 +++--- .github/workflows/nightly-ci.yml | 6 +++--- .github/workflows/pr_integration_tests.yml | 6 +++--- .github/workflows/pr_local_integration_tests.yml | 6 +++--- .github/workflows/unit_tests.yml | 6 +++--- 11 files changed, 33 insertions(+), 35 deletions(-) diff --git a/.github/fork_workflows/fork_pr_integration_tests_aws.yml b/.github/fork_workflows/fork_pr_integration_tests_aws.yml index ab5130c704e..7261833ae6b 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_aws.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_aws.yml @@ -109,9 +109,6 @@ jobs: aws-region: us-west-2 - name: Use AWS CLI run: aws sts get-caller-identity - - name: Upgrade pip version - run: | - pip install --upgrade "pip>=21.3.1,<22.3" - name: Get pip cache dir id: pip-cache run: | @@ -126,6 +123,9 @@ jobs: key: ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip-${{ hashFiles(format('**/py{0}-ci-requirements.txt', env.PYTHON)) }} restore-keys: | ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip- + - name: Upgrade pip version + run: | + pip install --upgrade "pip>=21.3.1,<22.3" - name: Install pip-tools run: pip install pip-tools - name: Install apache-arrow on ubuntu diff --git a/.github/fork_workflows/fork_pr_integration_tests_gcp.yml b/.github/fork_workflows/fork_pr_integration_tests_gcp.yml index 4b74c0ab096..1a05c068b50 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_gcp.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_gcp.yml @@ -53,9 +53,6 @@ jobs: project_id: ${{ secrets.GCP_PROJECT_ID }} - name: Use gcloud CLI run: gcloud info - - name: Upgrade pip version - run: | - pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | @@ -70,6 +67,9 @@ jobs: key: ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip-${{ hashFiles(format('**/py{0}-ci-requirements.txt', env.PYTHON)) }} restore-keys: | ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip- + - name: Upgrade pip version + run: | + pip install --upgrade "pip>=21.3.1,<23.2" - name: Install pip-tools run: pip install pip-tools - name: Install apache-arrow on ubuntu diff --git a/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml b/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml index cef970ab16a..9327f5c7294 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml @@ -43,10 +43,6 @@ jobs: uses: actions/setup-go@v2 with: go-version: 1.18.0 - - - name: Upgrade pip version - run: | - pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | @@ -61,6 +57,9 @@ jobs: key: ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip-${{ hashFiles(format('**/py{0}-ci-requirements.txt', env.PYTHON)) }} restore-keys: | ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip- + - name: Upgrade pip version + run: | + pip install --upgrade "pip>=21.3.1,<23.2" - name: Install pip-tools run: pip install pip-tools - name: Install apache-arrow on ubuntu diff --git a/.github/workflows/java_master_only.yml b/.github/workflows/java_master_only.yml index b15ddddc5d7..d82f69dd3cb 100644 --- a/.github/workflows/java_master_only.yml +++ b/.github/workflows/java_master_only.yml @@ -112,9 +112,6 @@ jobs: with: python-version: 3.8 architecture: x64 - - name: Upgrade pip version - run: | - pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | @@ -129,9 +126,11 @@ jobs: key: ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip-${{ hashFiles(format('**/py{0}-ci-requirements.txt', env.PYTHON)) }} restore-keys: | ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip- + - name: Upgrade pip version + run: | + pip install --upgrade "pip>=21.3.1,<23.2" - name: Install pip-tools run: pip install pip-tools - - name: Install Python dependencies run: make install-python-ci-dependencies - uses: actions/cache@v2 diff --git a/.github/workflows/java_pr.yml b/.github/workflows/java_pr.yml index a927587d7d3..83c52e7dbfd 100644 --- a/.github/workflows/java_pr.yml +++ b/.github/workflows/java_pr.yml @@ -148,9 +148,6 @@ jobs: with: python-version: 3.8 architecture: x64 - - name: Upgrade pip version - run: | - pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | @@ -165,6 +162,9 @@ jobs: key: ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip-${{ hashFiles(format('**/py{0}-ci-requirements.txt', env.PYTHON)) }} restore-keys: | ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip- + - name: Upgrade pip version + run: | + pip install --upgrade "pip>=21.3.1,<23.2" - name: Install pip-tools run: pip install pip-tools - name: Install Python dependencies diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index c2112ea303f..a4a42a11edb 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -15,9 +15,6 @@ jobs: with: python-version: "3.8" architecture: x64 - - name: Upgrade pip version - run: | - pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | @@ -32,6 +29,9 @@ jobs: key: ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip-${{ hashFiles(format('**/py{0}-ci-requirements.txt', env.PYTHON)) }} restore-keys: | ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip- + - name: Upgrade pip version + run: | + pip install --upgrade "pip>=21.3.1,<23.2" - name: Install pip-tools run: pip install pip-tools - name: Install dependencies diff --git a/.github/workflows/master_only.yml b/.github/workflows/master_only.yml index a7d412fd4ac..580ea3171b3 100644 --- a/.github/workflows/master_only.yml +++ b/.github/workflows/master_only.yml @@ -106,9 +106,6 @@ jobs: aws-region: us-west-2 - name: Use AWS CLI run: aws sts get-caller-identity - - name: Upgrade pip version - run: | - pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | @@ -123,6 +120,9 @@ jobs: key: ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip-${{ hashFiles(format('**/py{0}-ci-requirements.txt', env.PYTHON)) }} restore-keys: | ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip- + - name: Upgrade pip version + run: | + pip install --upgrade "pip>=21.3.1,<23.2" - name: Install pip-tools run: pip install pip-tools - name: Install dependencies diff --git a/.github/workflows/nightly-ci.yml b/.github/workflows/nightly-ci.yml index 03078c0a788..0e1df81262d 100644 --- a/.github/workflows/nightly-ci.yml +++ b/.github/workflows/nightly-ci.yml @@ -173,9 +173,6 @@ jobs: aws-region: us-west-2 - name: Use AWS CLI run: aws sts get-caller-identity - - name: Upgrade pip version - run: | - pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | @@ -190,6 +187,9 @@ jobs: key: ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip-${{ hashFiles(format('**/py{0}-ci-requirements.txt', env.PYTHON)) }} restore-keys: | ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip- + - name: Upgrade pip version + run: | + pip install --upgrade "pip>=21.3.1,<23.2" - name: Install pip-tools run: pip install pip-tools - name: Install apache-arrow on ubuntu diff --git a/.github/workflows/pr_integration_tests.yml b/.github/workflows/pr_integration_tests.yml index ed02636c993..73344ec2ddd 100644 --- a/.github/workflows/pr_integration_tests.yml +++ b/.github/workflows/pr_integration_tests.yml @@ -133,9 +133,6 @@ jobs: aws-region: us-west-2 - name: Use AWS CLI run: aws sts get-caller-identity - - name: Upgrade pip version - run: | - pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | @@ -150,6 +147,9 @@ jobs: key: ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip-${{ hashFiles(format('**/py{0}-ci-requirements.txt', env.PYTHON)) }} restore-keys: | ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip- + - name: Upgrade pip version + run: | + pip install --upgrade "pip>=21.3.1,<23.2" - name: Install pip-tools run: pip install pip-tools - name: Install dependencies diff --git a/.github/workflows/pr_local_integration_tests.yml b/.github/workflows/pr_local_integration_tests.yml index 1a2c0790d1a..111a9b51a9c 100644 --- a/.github/workflows/pr_local_integration_tests.yml +++ b/.github/workflows/pr_local_integration_tests.yml @@ -38,9 +38,6 @@ jobs: with: python-version: ${{ matrix.python-version }} architecture: x64 - - name: Upgrade pip version - run: | - pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | @@ -55,6 +52,9 @@ jobs: key: ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip-${{ hashFiles(format('**/py{0}-ci-requirements.txt', env.PYTHON)) }} restore-keys: | ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip- + - name: Upgrade pip version + run: | + pip install --upgrade "pip>=21.3.1,<23.2" - name: Install pip-tools run: pip install pip-tools - name: Install dependencies diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 538a5819799..f03cd33346c 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -36,9 +36,6 @@ jobs: run: | brew install zlib ln -sv $(brew --prefix zlib)/lib/libz.dylib $(brew --prefix)/lib/libzlib.dylib - - name: Upgrade pip version - run: | - pip install --upgrade "pip>=21.3.1,<23.2" - name: Get pip cache dir id: pip-cache run: | @@ -53,6 +50,9 @@ jobs: key: ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip-${{ hashFiles(format('**/py{0}-ci-requirements.txt', env.PYTHON)) }} restore-keys: | ${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-pip- + - name: Upgrade pip version + run: | + pip install --upgrade "pip>=21.3.1,<23.2" - name: Install pip-tools run: pip install pip-tools - name: Install dependencies From 8e2a3b456068afa43fcce38c06af79e663fab72e Mon Sep 17 00:00:00 2001 From: Mark Snidal Date: Tue, 5 Sep 2023 02:36:03 -0400 Subject: [PATCH 036/113] fix: Handle unknown postgres source types gracefully (#3634) Handle more pg types gracefully Signed-off-by: Mark Snidal Signed-off-by: Attila Toth --- sdk/python/feast/type_map.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/sdk/python/feast/type_map.py b/sdk/python/feast/type_map.py index df853462836..52e28907505 100644 --- a/sdk/python/feast/type_map.py +++ b/sdk/python/feast/type_map.py @@ -873,13 +873,26 @@ def feast_value_type_to_pa( def pg_type_code_to_pg_type(code: int) -> str: - return { + """ Map the postgres type code a Feast type string + + Rather than raise an exception on an unknown type, we return the + string representation of the type code. This way rather than raising + an exception on unknown types, Feast will just skip the problem columns. + + Note that json and jsonb are not supported but this shows up in the + log as a warning. Since postgres allows custom types we return an unknown for those cases. + + See: https://jdbc.postgresql.org/documentation/publicapi/index.html?constant-values.html + """ + PG_TYPE_MAP = { 16: "boolean", 17: "bytea", 20: "bigint", 21: "smallint", 23: "integer", 25: "text", + 114: "json", + 199: "json[]", 700: "real", 701: "double precision", 1000: "boolean[]", @@ -905,7 +918,11 @@ def pg_type_code_to_pg_type(code: int) -> str: 1700: "numeric", 2950: "uuid", 2951: "uuid[]", - }[code] + 3802: "jsonb", + 3807: "jsonb[]", + } + + return PG_TYPE_MAP.get(code, "unknown") def pg_type_code_to_arrow(code: int) -> str: From 1966cdec9cd567334894b455fb8f396f16bbf73f Mon Sep 17 00:00:00 2001 From: Danny C Date: Tue, 5 Sep 2023 00:15:59 -0700 Subject: [PATCH 037/113] chore: Fix linting issue Signed-off-by: Danny C Signed-off-by: Attila Toth --- sdk/python/feast/type_map.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/python/feast/type_map.py b/sdk/python/feast/type_map.py index 52e28907505..d246fb40545 100644 --- a/sdk/python/feast/type_map.py +++ b/sdk/python/feast/type_map.py @@ -873,10 +873,10 @@ def feast_value_type_to_pa( def pg_type_code_to_pg_type(code: int) -> str: - """ Map the postgres type code a Feast type string + """Map the postgres type code a Feast type string Rather than raise an exception on an unknown type, we return the - string representation of the type code. This way rather than raising + string representation of the type code. This way rather than raising an exception on unknown types, Feast will just skip the problem columns. Note that json and jsonb are not supported but this shows up in the From c671cbdbb795af220c23e937a835d75e144b2d99 Mon Sep 17 00:00:00 2001 From: Ren Date: Tue, 5 Sep 2023 03:18:55 -0400 Subject: [PATCH 038/113] docs: Add Dragonfly as an online-store option to Feast Readme and docs (#3647) * Add dragonfly to feast Readme and docs Signed-off-by: Danny C * Remove new lines Signed-off-by: Danny C * Remove more newlines Signed-off-by: Danny C * rebase and fix using template generation Signed-off-by: Danny C --------- Signed-off-by: Danny C Co-authored-by: Danny C Signed-off-by: Attila Toth --- README.md | 1 + docs/reference/online-stores/dragonfly.md | 90 +++++++++++++++++++++++ docs/roadmap.md | 1 + 3 files changed, 92 insertions(+) create mode 100644 docs/reference/online-stores/dragonfly.md diff --git a/README.md b/README.md index 1152aa060e4..f2c9348b1cc 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,7 @@ The list below contains the functionality that contributors are planning to deve * [x] [Datastore](https://docs.feast.dev/reference/online-stores/datastore) * [x] [Bigtable](https://docs.feast.dev/reference/online-stores/bigtable) * [x] [SQLite](https://docs.feast.dev/reference/online-stores/sqlite) + * [x] [Dragonfly](https://docs.feast.dev/reference/online-stores/dragonfly) * [x] [Azure Cache for Redis (community plugin)](https://github.com/Azure/feast-azure) * [x] [Postgres (contrib plugin)](https://docs.feast.dev/reference/online-stores/postgres) * [x] [Cassandra / AstraDB (contrib plugin)](https://docs.feast.dev/reference/online-stores/cassandra) diff --git a/docs/reference/online-stores/dragonfly.md b/docs/reference/online-stores/dragonfly.md new file mode 100644 index 00000000000..bcd814ecc45 --- /dev/null +++ b/docs/reference/online-stores/dragonfly.md @@ -0,0 +1,90 @@ +# Dragonfly online store + +## Description + +[Dragonfly](https://github.com/dragonflydb/dragonfly) is a modern in-memory datastore that implements novel algorithms and data structures on top of a multi-threaded, share-nothing architecture. Thanks to its API compatibility, Dragonfly can act as a drop-in replacement for Redis. Due to Dragonfly's hardware efficiency, you can run a single node instance on a small 8GB instance or scale vertically to large 768GB machines with 64 cores. This greatly reduces infrastructure costs as well as architectural complexity. + +Similar to Redis, Dragonfly can be used as an online feature store for Feast. + +## Using Dragonfly as a drop-in Feast online store instead of Redis + +Make sure you have Python and `pip` installed. + +Install the Feast SDK and CLI + +`pip install feast` + +In order to use Dragonfly as the online store, you'll need to install the redis extra: + +`pip install 'feast[redis]'` + +### 1. Create a feature repository + +Bootstrap a new feature repository: + +``` +feast init feast_dragonfly +cd feast_dragonfly/feature_repo +``` + +Update `feature_repo/feature_store.yaml` with the below contents: + +``` +project: feast_dragonfly +registry: data/registry.db +provider: local +online_store: +type: redis +connection_string: "localhost:6379" +``` + +### 2. Start Dragonfly + +There are several options available to get Dragonfly up and running quickly. We will be using Docker for this tutorial. + +`docker run --network=host --ulimit memlock=-1 docker.dragonflydb.io/dragonflydb/dragonfly` + +### 3. Register feature definitions and deploy your feature store + +`feast apply` + +The `apply` command scans python files in the current directory (`example_repo.py` in this case) for feature view/entity definitions, registers the objects, and deploys infrastructure. +You should see the following output: + +``` +.... +Created entity driver +Created feature view driver_hourly_stats_fresh +Created feature view driver_hourly_stats +Created on demand feature view transformed_conv_rate +Created on demand feature view transformed_conv_rate_fresh +Created feature service driver_activity_v1 +Created feature service driver_activity_v3 +Created feature service driver_activity_v2 +``` + +## Functionality Matrix + +The set of functionality supported by online stores is described in detail [here](overview.md#functionality). +Below is a matrix indicating which functionality is supported by the Redis online store. + +| | Redis | +| :-------------------------------------------------------- | :---- | +| write feature values to the online store | yes | +| read feature values from the online store | yes | +| update infrastructure (e.g. tables) in the online store | yes | +| teardown infrastructure (e.g. tables) in the online store | yes | +| generate a plan of infrastructure changes | no | +| support for on-demand transforms | yes | +| readable by Python SDK | yes | +| readable by Java | yes | +| readable by Go | yes | +| support for entityless feature views | yes | +| support for concurrent writing to the same key | yes | +| support for ttl (time to live) at retrieval | yes | +| support for deleting expired data | yes | +| collocated by feature view | no | +| collocated by feature service | no | +| collocated by entity key | yes | + +To compare this set of functionality against other online stores, please see the full [functionality matrix](overview.md#functionality-matrix). diff --git a/docs/roadmap.md b/docs/roadmap.md index e75e58849bf..d5dc88005bf 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -33,6 +33,7 @@ The list below contains the functionality that contributors are planning to deve * [x] [Datastore](https://docs.feast.dev/reference/online-stores/datastore) * [x] [Bigtable](https://docs.feast.dev/reference/online-stores/bigtable) * [x] [SQLite](https://docs.feast.dev/reference/online-stores/sqlite) + * [x] [Dragonfly](https://docs.feast.dev/reference/online-stores/dragonfly) * [x] [Azure Cache for Redis (community plugin)](https://github.com/Azure/feast-azure) * [x] [Postgres (contrib plugin)](https://docs.feast.dev/reference/online-stores/postgres) * [x] [Cassandra / AstraDB (contrib plugin)](https://docs.feast.dev/reference/online-stores/cassandra) From 96f485146eabc6b4098a50099943ae1422e024c8 Mon Sep 17 00:00:00 2001 From: crispin-ki <131684659+crispin-ki@users.noreply.github.com> Date: Tue, 5 Sep 2023 18:50:47 +0100 Subject: [PATCH 039/113] fix: Remove unwanted excessive splitting of gcs path, so expected gcs parquet paths are returned from BigQueryRetrievalJob.to_remote_storage() (#3730) Remove unwanted excessive splitting of gcs path Signed-off-by: Crispin Logan Signed-off-by: Attila Toth --- sdk/python/feast/infra/offline_stores/bigquery.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/python/feast/infra/offline_stores/bigquery.py b/sdk/python/feast/infra/offline_stores/bigquery.py index 5dd8f61bced..5913b60f62f 100644 --- a/sdk/python/feast/infra/offline_stores/bigquery.py +++ b/sdk/python/feast/infra/offline_stores/bigquery.py @@ -577,7 +577,6 @@ def to_remote_storage(self) -> List[str]: else: storage_client = StorageClient(project=self.client.project) bucket, prefix = self._gcs_path[len("gs://") :].split("/", 1) - prefix = prefix.rsplit("/", 1)[0] if prefix.startswith("/"): prefix = prefix[1:] From 30e96ab7fe79eef1361b83920b7162aa85917080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tokg=C3=B6z?= <56408993+mehmettokgoz@users.noreply.github.com> Date: Thu, 7 Sep 2023 07:50:17 +0300 Subject: [PATCH 040/113] feat: Implement gRPC server to ingest streaming features (#3687) * Implemented gRPC server for ingesting streaming features. Signed-off-by: mehmettokgoz Signed-off-by: Danny C Signed-off-by: Attila Toth --- Makefile | 2 +- protos/feast/serving/GrpcServer.proto | 27 ++ sdk/python/feast/cli.py | 31 ++ sdk/python/feast/infra/contrib/grpc_server.py | 95 ++++ .../requirements/py3.10-ci-requirements.txt | 400 +++++++++-------- .../requirements/py3.10-requirements.txt | 105 +++-- .../requirements/py3.8-ci-requirements.txt | 386 +++++++++-------- .../requirements/py3.8-requirements.txt | 109 +++-- .../requirements/py3.9-ci-requirements.txt | 408 +++++++++--------- .../requirements/py3.9-requirements.txt | 109 +++-- setup.py | 23 +- 11 files changed, 999 insertions(+), 696 deletions(-) create mode 100644 protos/feast/serving/GrpcServer.proto create mode 100644 sdk/python/feast/infra/contrib/grpc_server.py diff --git a/Makefile b/Makefile index cf8a899ac68..4b85c0e4483 100644 --- a/Makefile +++ b/Makefile @@ -353,7 +353,7 @@ kill-trino-locally: cd ${ROOT_DIR}; docker stop trino install-protoc-dependencies: - pip install --ignore-installed protobuf==4.23.4 grpcio-tools==1.47.0 mypy-protobuf==3.1.0 + pip install --ignore-installed protobuf==4.23.4 "grpcio-tools>=1.56.2,<2" mypy-protobuf==3.1.0 install-feast-ci-locally: pip install -e ".[ci]" diff --git a/protos/feast/serving/GrpcServer.proto b/protos/feast/serving/GrpcServer.proto new file mode 100644 index 00000000000..cd0274c5c75 --- /dev/null +++ b/protos/feast/serving/GrpcServer.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +message PushRequest { + map features = 1; + string stream_feature_view = 2; + bool allow_registry_cache = 3; + string to = 4; +} + +message PushResponse { + bool status = 1; +} + +message WriteToOnlineStoreRequest { + map features = 1; + string feature_view_name = 2; + bool allow_registry_cache = 3; +} + +message WriteToOnlineStoreResponse { + bool status = 1; +} + +service GrpcFeatureServer { + rpc Push (PushRequest) returns (PushResponse) {}; + rpc WriteToOnlineStore (WriteToOnlineStoreRequest) returns (WriteToOnlineStoreResponse); +} \ No newline at end of file diff --git a/sdk/python/feast/cli.py b/sdk/python/feast/cli.py index 229cb992321..8c2c326b595 100644 --- a/sdk/python/feast/cli.py +++ b/sdk/python/feast/cli.py @@ -28,6 +28,7 @@ from feast.constants import DEFAULT_FEATURE_TRANSFORMATION_SERVER_PORT from feast.errors import FeastObjectNotFoundException, FeastProviderLoginError from feast.feature_view import FeatureView +from feast.infra.contrib.grpc_server import get_grpc_server from feast.on_demand_feature_view import OnDemandFeatureView from feast.repo_config import load_repo_config from feast.repo_operations import ( @@ -689,6 +690,36 @@ def serve_command( ) +@cli.command("listen") +@click.option( + "--address", + "-a", + type=click.STRING, + default="localhost:50051", + show_default=True, + help="Address of the gRPC server", +) +@click.option( + "--max_workers", + "-w", + type=click.INT, + default=10, + show_default=False, + help="The maximum number of threads that can be used to execute the gRPC calls", +) +@click.pass_context +def listen_command( + ctx: click.Context, + address: str, + max_workers: int, +): + """Start a gRPC feature server to ingest streaming features on given address""" + store = create_feature_store(ctx) + server = get_grpc_server(address, store, max_workers) + server.start() + server.wait_for_termination() + + @cli.command("serve_transformations") @click.option( "--port", diff --git a/sdk/python/feast/infra/contrib/grpc_server.py b/sdk/python/feast/infra/contrib/grpc_server.py new file mode 100644 index 00000000000..2017f1095b2 --- /dev/null +++ b/sdk/python/feast/infra/contrib/grpc_server.py @@ -0,0 +1,95 @@ +import logging +from concurrent import futures + +import grpc +import pandas as pd +from grpc_health.v1 import health, health_pb2_grpc + +from feast.data_source import PushMode +from feast.errors import PushSourceNotFoundException +from feast.feature_store import FeatureStore +from feast.protos.feast.serving.GrpcServer_pb2 import ( + PushResponse, + WriteToOnlineStoreResponse, +) +from feast.protos.feast.serving.GrpcServer_pb2_grpc import ( + GrpcFeatureServerServicer, + add_GrpcFeatureServerServicer_to_server, +) + + +def parse(features): + df = {} + for i in features.keys(): + df[i] = [features.get(i)] + return pd.DataFrame.from_dict(df) + + +class GrpcFeatureServer(GrpcFeatureServerServicer): + fs: FeatureStore + + def __init__(self, fs: FeatureStore): + self.fs = fs + super().__init__() + + def Push(self, request, context): + try: + df = parse(request.features) + if request.to == "offline": + to = PushMode.OFFLINE + elif request.to == "online": + to = PushMode.ONLINE + elif request.to == "online_and_offline": + to = PushMode.ONLINE_AND_OFFLINE + else: + raise ValueError( + f"{request.to} is not a supported push format. Please specify one of these ['online', 'offline', " + f"'online_and_offline']." + ) + self.fs.push( + push_source_name=request.push_source_name, + df=df, + allow_registry_cache=request.allow_registry_cache, + to=to, + ) + except PushSourceNotFoundException as e: + logging.exception(str(e)) + context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_details(str(e)) + return PushResponse(status=False) + except Exception as e: + logging.exception(str(e)) + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + return PushResponse(status=False) + return PushResponse(status=True) + + def WriteToOnlineStore(self, request, context): + logging.warning( + "write_to_online_store is deprecated. Please consider using Push instead" + ) + try: + df = parse(request.features) + self.fs.write_to_online_store( + feature_view_name=request.feature_view_name, + df=df, + allow_registry_cache=request.allow_registry_cache, + ) + except Exception as e: + logging.exception(str(e)) + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + return PushResponse(status=False) + return WriteToOnlineStoreResponse(status=True) + + +def get_grpc_server(address: str, fs: FeatureStore, max_workers: int): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=max_workers)) + add_GrpcFeatureServerServicer_to_server(GrpcFeatureServer(fs), server) + health_servicer = health.HealthServicer( + experimental_non_blocking=True, + experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=max_workers), + ) + health_pb2_grpc.add_HealthServicer_to_server(health_servicer, server) + server.add_insecure_port(address) + return server diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index 2f28a271dc3..cb72fdaa350 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -8,7 +8,7 @@ adal==1.2.7 # via msrestazure adlfs==0.5.9 # via feast (setup.py) -aiohttp==3.8.4 +aiohttp==3.8.5 # via # adlfs # gcsfs @@ -18,7 +18,7 @@ alabaster==0.7.13 # via sphinx altair==4.2.0 # via great-expectations -anyio==3.7.0 +anyio==4.0.0 # via # httpcore # jupyter-server @@ -30,11 +30,8 @@ appnope==0.1.3 # via # ipykernel # ipython -argon2-cffi==21.3.0 - # via - # jupyter-server - # nbclassic - # notebook +argon2-cffi==23.1.0 + # via jupyter-server argon2-cffi-bindings==21.2.0 # via argon2-cffi arrow==1.2.3 @@ -45,9 +42,11 @@ asn1crypto==1.5.1 # snowflake-connector-python assertpy==1.1 # via feast (setup.py) -asttokens==2.2.1 +asttokens==2.4.0 # via stack-data -async-timeout==4.0.2 +async-lru==2.0.4 + # via jupyterlab +async-timeout==4.0.3 # via # aiohttp # redis @@ -56,9 +55,10 @@ attrs==23.1.0 # aiohttp # bowler # jsonschema + # referencing avro==1.10.0 # via feast (setup.py) -azure-core==1.27.0 +azure-core==1.29.3 # via # adlfs # azure-identity @@ -66,16 +66,18 @@ azure-core==1.27.0 # msrest azure-datalake-store==0.0.53 # via adlfs -azure-identity==1.13.0 +azure-identity==1.14.0 # via # adlfs # feast (setup.py) -azure-storage-blob==12.16.0 +azure-storage-blob==12.17.0 # via # adlfs # feast (setup.py) babel==2.12.1 - # via sphinx + # via + # jupyterlab-server + # sphinx backcall==0.2.0 # via ipython beautifulsoup4==4.12.2 @@ -84,30 +86,30 @@ black==22.12.0 # via feast (setup.py) bleach==6.0.0 # via nbconvert -boto3==1.26.146 +boto3==1.28.42 # via # feast (setup.py) # moto -botocore==1.29.146 +botocore==1.31.42 # via # boto3 # moto # s3transfer bowler==0.9.0 # via feast (setup.py) -build==0.10.0 +build==1.0.3 # via # feast (setup.py) # pip-tools bytewax==0.15.1 # via feast (setup.py) -cachecontrol==0.13.0 +cachecontrol==0.13.1 # via firebase-admin cachetools==5.3.1 # via google-auth -cassandra-driver==3.27.0 +cassandra-driver==3.28.0 # via feast (setup.py) -certifi==2023.5.7 +certifi==2023.7.22 # via # httpcore # httpx @@ -122,14 +124,14 @@ cffi==1.15.1 # azure-datalake-store # cryptography # snowflake-connector-python -cfgv==3.3.1 +cfgv==3.4.0 # via pre-commit -charset-normalizer==3.1.0 +charset-normalizer==3.2.0 # via # aiohttp # requests # snowflake-connector-python -click==8.1.3 +click==8.1.7 # via # black # bowler @@ -146,16 +148,17 @@ colorama==0.4.6 # via # feast (setup.py) # great-expectations -comm==0.1.3 - # via ipykernel -coverage[toml]==7.2.7 +comm==0.1.4 + # via + # ipykernel + # ipywidgets +coverage[toml]==7.3.1 # via pytest-cov -cryptography==40.0.2 +cryptography==41.0.3 # via # adal # azure-identity # azure-storage-blob - # cassandra-driver # feast (setup.py) # great-expectations # moto @@ -165,11 +168,11 @@ cryptography==40.0.2 # snowflake-connector-python # types-pyopenssl # types-redis -dask==2023.5.1 +dask==2023.9.1 # via feast (setup.py) db-dtypes==1.1.1 # via google-cloud-bigquery -debugpy==1.6.7 +debugpy==1.6.7.post1 # via ipykernel decorator==5.1.1 # via @@ -181,12 +184,12 @@ deprecated==1.2.14 # via redis deprecation==2.1.0 # via testcontainers -dill==0.3.6 +dill==0.3.7 # via # bytewax # feast (setup.py) # multiprocess -distlib==0.3.6 +distlib==0.3.7 # via virtualenv docker==6.1.3 # via @@ -196,23 +199,24 @@ docutils==0.19 # via sphinx entrypoints==0.4 # via altair -exceptiongroup==1.1.1 +exceptiongroup==1.1.3 # via # anyio + # ipython # pytest -execnet==1.9.0 +execnet==2.0.2 # via pytest-xdist executing==1.2.0 # via stack-data -fastapi==0.95.2 +fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.1 +fastavro==1.8.2 # via # feast (setup.py) # pandavro -fastjsonschema==2.17.1 +fastjsonschema==2.18.0 # via nbformat -filelock==3.12.0 +filelock==3.12.3 # via # snowflake-connector-python # virtualenv @@ -224,7 +228,7 @@ flake8==6.0.0 # via feast (setup.py) fqdn==1.5.1 # via jsonschema -frozenlist==1.3.3 +frozenlist==1.4.0 # via # aiohttp # aiosignal @@ -239,7 +243,7 @@ geojson==2.5.0 # via rockset geomet==0.2.1.post1 # via cassandra-driver -google-api-core[grpc]==2.11.0 +google-api-core[grpc]==2.11.1 # via # feast (setup.py) # firebase-admin @@ -251,9 +255,9 @@ google-api-core[grpc]==2.11.0 # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.88.0 +google-api-python-client==2.98.0 # via firebase-admin -google-auth==2.19.1 +google-auth==2.22.0 # via # gcsfs # google-api-core @@ -267,35 +271,35 @@ google-auth-httplib2==0.1.0 # via google-api-python-client google-auth-oauthlib==1.0.0 # via gcsfs -google-cloud-bigquery[pandas]==3.11.0 +google-cloud-bigquery[pandas]==3.11.4 # via feast (setup.py) -google-cloud-bigquery-storage==2.20.0 +google-cloud-bigquery-storage==2.22.0 # via feast (setup.py) -google-cloud-bigtable==2.18.1 +google-cloud-bigtable==2.21.0 # via feast (setup.py) -google-cloud-core==2.3.2 +google-cloud-core==2.3.3 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-cloud-datastore==2.15.2 +google-cloud-datastore==2.18.0 # via feast (setup.py) google-cloud-firestore==2.11.1 # via firebase-admin -google-cloud-storage==2.9.0 +google-cloud-storage==2.10.0 # via # feast (setup.py) # firebase-admin # gcsfs google-crc32c==1.5.0 # via google-resumable-media -google-resumable-media==2.5.0 +google-resumable-media==2.6.0 # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.59.0 +googleapis-common-protos[grpc]==1.60.0 # via # feast (setup.py) # google-api-core @@ -303,30 +307,31 @@ googleapis-common-protos[grpc]==1.59.0 # grpcio-status great-expectations==0.15.50 # via feast (setup.py) -greenlet==2.0.2 - # via sqlalchemy grpc-google-iam-v1==0.12.6 # via google-cloud-bigtable -grpcio==1.54.2 +grpcio==1.57.0 # via # feast (setup.py) # google-api-core # google-cloud-bigquery # googleapis-common-protos # grpc-google-iam-v1 + # grpcio-health-checking # grpcio-reflection # grpcio-status # grpcio-testing # grpcio-tools -grpcio-reflection==1.54.2 +grpcio-health-checking==1.57.0 # via feast (setup.py) -grpcio-status==1.54.2 +grpcio-reflection==1.57.0 + # via feast (setup.py) +grpcio-status==1.57.0 # via google-api-core -grpcio-testing==1.54.2 +grpcio-testing==1.57.0 # via feast (setup.py) -grpcio-tools==1.54.2 +grpcio-tools==1.57.0 # via feast (setup.py) -gunicorn==20.1.0 +gunicorn==21.2.0 # via feast (setup.py) h11==0.14.0 # via @@ -334,21 +339,21 @@ h11==0.14.0 # uvicorn happybase==1.2.0 # via feast (setup.py) -hazelcast-python-client==5.2.0 +hazelcast-python-client==5.3.0 # via feast (setup.py) hiredis==2.2.3 # via feast (setup.py) -httpcore==0.17.2 +httpcore==0.17.3 # via httpx httplib2==0.22.0 # via # google-api-python-client # google-auth-httplib2 -httptools==0.5.0 +httptools==0.6.0 # via uvicorn httpx==0.24.1 # via feast (setup.py) -identify==2.5.24 +identify==2.5.27 # via pre-commit idna==3.4 # via @@ -360,27 +365,20 @@ idna==3.4 # yarl imagesize==1.4.1 # via sphinx -importlib-metadata==6.6.0 +importlib-metadata==6.8.0 # via # dask # great-expectations iniconfig==2.0.0 # via pytest -ipykernel==6.23.1 - # via - # ipywidgets - # nbclassic - # notebook -ipython==8.14.0 +ipykernel==6.25.2 + # via jupyterlab +ipython==8.15.0 # via # great-expectations # ipykernel # ipywidgets -ipython-genutils==0.2.0 - # via - # nbclassic - # notebook -ipywidgets==8.0.6 +ipywidgets==8.1.0 # via great-expectations isodate==0.6.1 # via @@ -390,7 +388,7 @@ isoduration==20.11.0 # via jsonschema isort==5.12.0 # via feast (setup.py) -jedi==0.18.2 +jedi==0.19.0 # via ipython jinja2==3.1.2 # via @@ -398,56 +396,69 @@ jinja2==3.1.2 # feast (setup.py) # great-expectations # jupyter-server + # jupyterlab + # jupyterlab-server # moto - # nbclassic # nbconvert - # notebook # sphinx jmespath==1.0.1 # via # boto3 # botocore -jsonpatch==1.32 +json5==0.9.14 + # via jupyterlab-server +jsonpatch==1.33 # via great-expectations -jsonpointer==2.3 +jsonpointer==2.4 # via # jsonpatch # jsonschema -jsonschema[format-nongpl]==4.17.3 +jsonschema[format-nongpl]==4.19.0 # via # altair # feast (setup.py) # great-expectations # jupyter-events + # jupyterlab-server # nbformat -jupyter-client==8.2.0 +jsonschema-specifications==2023.7.1 + # via jsonschema +jupyter-client==8.3.1 # via # ipykernel # jupyter-server - # nbclassic # nbclient - # notebook -jupyter-core==5.3.0 +jupyter-core==5.3.1 # via # ipykernel # jupyter-client # jupyter-server - # nbclassic + # jupyterlab # nbclient # nbconvert # nbformat - # notebook -jupyter-events==0.6.3 +jupyter-events==0.7.0 # via jupyter-server -jupyter-server==2.6.0 +jupyter-lsp==2.2.0 + # via jupyterlab +jupyter-server==2.7.3 # via - # nbclassic + # jupyter-lsp + # jupyterlab + # jupyterlab-server + # notebook # notebook-shim jupyter-server-terminals==0.4.4 # via jupyter-server +jupyterlab==4.0.5 + # via notebook jupyterlab-pygments==0.2.2 # via nbconvert -jupyterlab-widgets==3.0.7 +jupyterlab-server==2.24.0 + # via + # jupyterlab + # notebook +jupyterlab-widgets==3.0.8 # via ipywidgets kubernetes==20.13.0 # via feast (setup.py) @@ -460,7 +471,7 @@ markupsafe==2.1.3 # jinja2 # nbconvert # werkzeug -marshmallow==3.19.0 +marshmallow==3.20.1 # via great-expectations matplotlib-inline==0.1.6 # via @@ -470,19 +481,19 @@ mccabe==0.7.0 # via flake8 minio==7.1.0 # via feast (setup.py) -mistune==2.0.5 +mistune==3.0.1 # via # great-expectations # nbconvert -mmh3==4.0.0 +mmh3==4.0.1 # via feast (setup.py) mock==2.0.0 # via feast (setup.py) moreorless==0.4.0 # via bowler -moto==4.1.10 +moto==4.2.2 # via feast (setup.py) -msal==1.22.0 +msal==1.23.0 # via # azure-datalake-store # azure-identity @@ -499,7 +510,7 @@ multidict==6.0.4 # via # aiohttp # yarl -multiprocess==0.70.14 +multiprocess==0.70.15 # via bytewax mypy==0.982 # via @@ -511,37 +522,29 @@ mypy-extensions==1.0.0 # mypy mypy-protobuf==3.1 # via feast (setup.py) -mysqlclient==2.1.1 +mysqlclient==2.2.0 # via feast (setup.py) -nbclassic==1.0.0 - # via notebook nbclient==0.8.0 # via nbconvert -nbconvert==7.4.0 - # via - # jupyter-server - # nbclassic - # notebook -nbformat==5.9.0 +nbconvert==7.8.0 + # via jupyter-server +nbformat==5.9.2 # via # great-expectations # jupyter-server - # nbclassic # nbclient # nbconvert - # notebook -nest-asyncio==1.5.6 - # via - # ipykernel - # nbclassic - # notebook +nest-asyncio==1.5.7 + # via ipykernel nodeenv==1.8.0 # via pre-commit -notebook==6.5.4 +notebook==7.0.3 # via great-expectations notebook-shim==0.2.3 - # via nbclassic -numpy==1.24.3 + # via + # jupyterlab + # notebook +numpy==1.25.2 # via # altair # db-dtypes @@ -555,7 +558,7 @@ oauthlib==3.2.2 # via requests-oauthlib oscrypto==1.3.0 # via snowflake-connector-python -overrides==7.3.1 +overrides==7.4.0 # via jupyter-server packaging==23.1 # via @@ -566,8 +569,11 @@ packaging==23.1 # docker # google-cloud-bigquery # great-expectations + # gunicorn # ipykernel # jupyter-server + # jupyterlab + # jupyterlab-server # marshmallow # nbconvert # pytest @@ -591,7 +597,7 @@ parso==0.8.3 # via jedi partd==1.4.0 # via dask -pathspec==0.11.1 +pathspec==0.11.2 # via black pbr==5.11.1 # via mock @@ -599,29 +605,27 @@ pexpect==4.8.0 # via ipython pickleshare==0.7.5 # via ipython -pip-tools==6.13.0 +pip-tools==7.3.0 # via feast (setup.py) -platformdirs==3.5.1 +platformdirs==3.8.1 # via # black # jupyter-core + # snowflake-connector-python # virtualenv -pluggy==1.0.0 +pluggy==1.3.0 # via pytest ply==3.11 # via thriftpy2 portalocker==2.7.0 # via msal-extensions -pre-commit==3.3.2 +pre-commit==3.3.1 # via feast (setup.py) -prometheus-client==0.17.0 - # via - # jupyter-server - # nbclassic - # notebook -prompt-toolkit==3.0.38 +prometheus-client==0.17.1 + # via jupyter-server +prompt-toolkit==3.0.39 # via ipython -proto-plus==1.22.2 +proto-plus==1.22.3 # via # feast (setup.py) # google-cloud-bigquery @@ -629,7 +633,7 @@ proto-plus==1.22.2 # google-cloud-bigtable # google-cloud-datastore # google-cloud-firestore -protobuf==4.23.2 +protobuf==4.23.3 # via # feast (setup.py) # google-api-core @@ -640,6 +644,7 @@ protobuf==4.23.2 # google-cloud-firestore # googleapis-common-protos # grpc-google-iam-v1 + # grpcio-health-checking # grpcio-reflection # grpcio-status # grpcio-testing @@ -650,7 +655,7 @@ psutil==5.9.0 # via # feast (setup.py) # ipykernel -psycopg2-binary==2.9.6 +psycopg2-binary==2.9.7 # via feast (setup.py) ptyprocess==0.7.0 # via @@ -684,43 +689,41 @@ pycparser==2.21 # via cffi pycryptodomex==3.18.0 # via snowflake-connector-python -pydantic==1.10.8 +pydantic==1.10.12 # via # fastapi # feast (setup.py) # great-expectations pyflakes==3.0.1 # via flake8 -pygments==2.15.1 +pygments==2.16.1 # via # feast (setup.py) # ipython # nbconvert # sphinx -pyjwt[crypto]==2.7.0 +pyjwt[crypto]==2.8.0 # via # adal # msal # snowflake-connector-python pymssql==2.2.8 # via feast (setup.py) -pymysql==1.0.3 +pymysql==1.1.0 # via feast (setup.py) pyodbc==4.0.39 # via feast (setup.py) pyopenssl==23.2.0 # via snowflake-connector-python -pyparsing==3.0.9 +pyparsing==3.1.1 # via # great-expectations # httplib2 pyproject-hooks==1.0.0 # via build -pyrsistent==0.19.3 - # via jsonschema -pyspark==3.4.0 +pyspark==3.4.1 # via feast (setup.py) -pytest==7.3.1 +pytest==7.4.1 # via # feast (setup.py) # pytest-benchmark @@ -761,7 +764,7 @@ python-dotenv==1.0.0 # via uvicorn python-json-logger==2.0.7 # via jupyter-events -pytz==2023.3 +pytz==2023.3.post1 # via # great-expectations # pandas @@ -776,16 +779,19 @@ pyyaml==6.0.1 # pre-commit # responses # uvicorn -pyzmq==25.1.0 +pyzmq==25.1.1 # via # ipykernel # jupyter-client # jupyter-server - # nbclassic - # notebook redis==4.2.2 # via feast (setup.py) -regex==2023.5.5 +referencing==0.30.2 + # via + # jsonschema + # jsonschema-specifications + # jupyter-events +regex==2023.8.8 # via feast (setup.py) requests==2.31.0 # via @@ -801,6 +807,7 @@ requests==2.31.0 # google-cloud-bigquery # google-cloud-storage # great-expectations + # jupyterlab-server # kubernetes # moto # msal @@ -815,7 +822,7 @@ requests-oauthlib==1.3.1 # google-auth-oauthlib # kubernetes # msrest -responses==0.23.1 +responses==0.23.3 # via moto rfc3339-validator==0.1.4 # via @@ -825,26 +832,26 @@ rfc3986-validator==0.1.1 # via # jsonschema # jupyter-events -rockset==2.0.0 +rockset==2.1.0 # via feast (setup.py) +rpds-py==0.10.2 + # via + # jsonschema + # referencing rsa==4.9 # via google-auth ruamel-yaml==0.17.17 # via great-expectations -s3transfer==0.6.1 +s3transfer==0.6.2 # via boto3 -scipy==1.10.1 +scipy==1.11.2 # via great-expectations send2trash==1.8.2 - # via - # jupyter-server - # nbclassic - # notebook + # via jupyter-server six==1.16.0 # via # asttokens # azure-core - # azure-identity # bleach # cassandra-driver # geomet @@ -866,29 +873,35 @@ sniffio==1.3.0 # httpx snowballstemmer==2.2.0 # via sphinx -snowflake-connector-python[pandas]==3.0.4 +snowflake-connector-python[pandas]==3.1.1 # via feast (setup.py) sortedcontainers==2.4.0 # via snowflake-connector-python -soupsieve==2.4.1 +soupsieve==2.5 # via beautifulsoup4 sphinx==6.2.1 - # via feast (setup.py) -sphinxcontrib-applehelp==1.0.4 + # via + # feast (setup.py) + # sphinxcontrib-applehelp + # sphinxcontrib-devhelp + # sphinxcontrib-htmlhelp + # sphinxcontrib-qthelp + # sphinxcontrib-serializinghtml +sphinxcontrib-applehelp==1.0.7 # via sphinx -sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-devhelp==1.0.5 # via sphinx -sphinxcontrib-htmlhelp==2.0.1 +sphinxcontrib-htmlhelp==2.0.4 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-qthelp==1.0.6 # via sphinx -sphinxcontrib-serializinghtml==1.1.5 +sphinxcontrib-serializinghtml==1.1.9 # via sphinx -sqlalchemy[mypy]==1.4.48 +sqlalchemy[mypy]==1.4.49 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a34 +sqlalchemy2-stubs==0.0.2a35 # via sqlalchemy stack-data==0.6.2 # via ipython @@ -896,14 +909,12 @@ starlette==0.27.0 # via fastapi tabulate==0.9.0 # via feast (setup.py) -tenacity==8.2.2 +tenacity==8.2.3 # via feast (setup.py) terminado==0.17.1 # via # jupyter-server # jupyter-server-terminals - # nbclassic - # notebook testcontainers==3.7.1 # via feast (setup.py) thriftpy2==0.4.16 @@ -917,23 +928,27 @@ tomli==2.0.1 # black # build # coverage + # jupyterlab # mypy + # pip-tools # pyproject-hooks # pytest +tomlkit==0.12.1 + # via snowflake-connector-python toolz==0.12.0 # via # altair # dask # partd -tornado==6.3.2 +tornado==6.3.3 # via # ipykernel # jupyter-client # jupyter-server - # nbclassic + # jupyterlab # notebook # terminado -tqdm==4.65.0 +tqdm==4.66.1 # via # feast (setup.py) # great-expectations @@ -947,12 +962,11 @@ traitlets==5.9.0 # jupyter-core # jupyter-events # jupyter-server + # jupyterlab # matplotlib-inline - # nbclassic # nbclient # nbconvert # nbformat - # notebook trino==0.326.0 # via feast (setup.py) typeguard==2.13.3 @@ -961,42 +975,46 @@ types-protobuf==3.19.22 # via # feast (setup.py) # mypy-protobuf -types-pymysql==1.0.19.7 +types-pymysql==1.1.0.1 # via feast (setup.py) -types-pyopenssl==23.2.0.0 +types-pyopenssl==23.2.0.2 # via types-redis -types-python-dateutil==2.8.19.13 +types-python-dateutil==2.8.19.14 # via feast (setup.py) -types-pytz==2023.3.0.0 +types-pytz==2023.3.0.1 # via feast (setup.py) -types-pyyaml==6.0.12.10 +types-pyyaml==6.0.12.11 # via # feast (setup.py) # responses -types-redis==4.5.5.2 +types-redis==4.6.0.5 # via feast (setup.py) -types-requests==2.31.0.1 +types-requests==2.31.0.2 # via feast (setup.py) -types-setuptools==67.8.0.0 +types-setuptools==68.2.0.0 # via feast (setup.py) -types-tabulate==0.9.0.2 +types-tabulate==0.9.0.3 # via feast (setup.py) -types-urllib3==1.26.25.13 +types-urllib3==1.26.25.14 # via types-requests -typing-extensions==4.6.3 +typing-extensions==4.7.1 # via + # async-lru # azure-core # azure-storage-blob + # fastapi + # filelock # great-expectations # mypy # pydantic # snowflake-connector-python # sqlalchemy2-stubs + # uvicorn tzlocal==5.0.1 # via # great-expectations # trino -uri-template==1.2.0 +uri-template==1.3.0 # via jsonschema uritemplate==4.1.1 # via google-api-python-client @@ -1013,15 +1031,17 @@ urllib3==1.26.16 # responses # rockset # snowflake-connector-python -uvicorn[standard]==0.22.0 +uvicorn[standard]==0.23.2 # via feast (setup.py) uvloop==0.17.0 # via uvicorn virtualenv==20.23.0 - # via pre-commit + # via + # feast (setup.py) + # pre-commit volatile==2.1.0 # via bowler -watchfiles==0.19.0 +watchfiles==0.20.0 # via uvicorn wcwidth==0.2.6 # via prompt-toolkit @@ -1031,18 +1051,18 @@ webencodings==0.5.1 # via # bleach # tinycss2 -websocket-client==1.5.2 +websocket-client==1.6.2 # via # docker # jupyter-server # kubernetes websockets==11.0.3 # via uvicorn -werkzeug==2.3.4 +werkzeug==2.3.7 # via moto -wheel==0.40.0 +wheel==0.41.2 # via pip-tools -widgetsnbextension==4.0.7 +widgetsnbextension==4.0.8 # via ipywidgets wrapt==1.15.0 # via @@ -1052,7 +1072,7 @@ xmltodict==0.13.0 # via moto yarl==1.9.2 # via aiohttp -zipp==3.15.0 +zipp==3.16.2 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: diff --git a/sdk/python/requirements/py3.10-requirements.txt b/sdk/python/requirements/py3.10-requirements.txt index d9b70d51974..4140bea9d0f 100644 --- a/sdk/python/requirements/py3.10-requirements.txt +++ b/sdk/python/requirements/py3.10-requirements.txt @@ -4,7 +4,7 @@ # # pip-compile --output-file=sdk/python/requirements/py3.10-requirements.txt # -anyio==3.7.0 +anyio==4.0.0 # via # httpcore # starlette @@ -15,16 +15,17 @@ attrs==23.1.0 # via # bowler # jsonschema + # referencing bowler==0.9.0 # via feast (setup.py) -certifi==2023.5.7 +certifi==2023.7.22 # via # httpcore # httpx # requests -charset-normalizer==3.1.0 +charset-normalizer==3.2.0 # via requests -click==8.1.3 +click==8.1.7 # via # bowler # dask @@ -35,39 +36,43 @@ cloudpickle==2.2.1 # via dask colorama==0.4.6 # via feast (setup.py) -dask==2023.5.1 +dask==2023.9.1 # via feast (setup.py) -dill==0.3.6 +dill==0.3.7 # via feast (setup.py) -exceptiongroup==1.1.1 +exceptiongroup==1.1.3 # via anyio -fastapi==0.95.2 +fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.1 +fastavro==1.8.2 # via # feast (setup.py) # pandavro fissix==21.11.13 # via bowler -fsspec==2023.5.0 +fsspec==2023.9.0 # via dask -greenlet==2.0.2 - # via sqlalchemy -grpcio==1.54.2 +grpcio==1.57.0 # via # feast (setup.py) + # grpcio-health-checking # grpcio-reflection -grpcio-reflection==1.54.2 + # grpcio-tools +grpcio-health-checking==1.57.0 + # via feast (setup.py) +grpcio-reflection==1.57.0 # via feast (setup.py) -gunicorn==20.1.0 +grpcio-tools==1.57.0 + # via feast (setup.py) +gunicorn==21.2.0 # via feast (setup.py) h11==0.14.0 # via # httpcore # uvicorn -httpcore==0.17.2 +httpcore==0.17.3 # via httpx -httptools==0.5.0 +httptools==0.6.0 # via uvicorn httpx==0.24.1 # via feast (setup.py) @@ -76,32 +81,38 @@ idna==3.4 # anyio # httpx # requests -importlib-metadata==6.6.0 +importlib-metadata==6.8.0 # via dask jinja2==3.1.2 # via feast (setup.py) -jsonschema==4.17.3 +jsonschema==4.19.0 # via feast (setup.py) +jsonschema-specifications==2023.7.1 + # via jsonschema locket==1.0.0 # via partd markupsafe==2.1.3 # via jinja2 -mmh3==4.0.0 +mmh3==4.0.1 # via feast (setup.py) moreorless==0.4.0 # via bowler -mypy==1.3.0 +mypy==1.5.1 # via sqlalchemy mypy-extensions==1.0.0 # via mypy -numpy==1.24.3 +mypy-protobuf==3.1 + # via feast (setup.py) +numpy==1.25.2 # via # feast (setup.py) # pandas # pandavro # pyarrow packaging==23.1 - # via dask + # via + # dask + # gunicorn pandas==1.5.3 # via # feast (setup.py) @@ -110,36 +121,45 @@ pandavro==1.5.2 # via feast (setup.py) partd==1.4.0 # via dask -proto-plus==1.22.2 +proto-plus==1.22.3 # via feast (setup.py) -protobuf==4.23.2 +protobuf==4.23.3 # via # feast (setup.py) + # grpcio-health-checking # grpcio-reflection + # grpcio-tools + # mypy-protobuf # proto-plus pyarrow==11.0.0 # via feast (setup.py) -pydantic==1.10.8 +pydantic==1.10.12 # via # fastapi # feast (setup.py) -pygments==2.15.1 +pygments==2.16.1 # via feast (setup.py) -pyrsistent==0.19.3 - # via jsonschema python-dateutil==2.8.2 # via pandas python-dotenv==1.0.0 # via uvicorn -pytz==2023.3 +pytz==2023.3.post1 # via pandas pyyaml==6.0.1 # via # dask # feast (setup.py) # uvicorn +referencing==0.30.2 + # via + # jsonschema + # jsonschema-specifications requests==2.31.0 # via feast (setup.py) +rpds-py==0.10.2 + # via + # jsonschema + # referencing six==1.16.0 # via # pandavro @@ -149,15 +169,15 @@ sniffio==1.3.0 # anyio # httpcore # httpx -sqlalchemy[mypy]==1.4.48 +sqlalchemy[mypy]==1.4.49 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a34 +sqlalchemy2-stubs==0.0.2a35 # via sqlalchemy starlette==0.27.0 # via fastapi tabulate==0.9.0 # via feast (setup.py) -tenacity==8.2.2 +tenacity==8.2.3 # via feast (setup.py) toml==0.10.2 # via feast (setup.py) @@ -167,26 +187,33 @@ toolz==0.12.0 # via # dask # partd -tqdm==4.65.0 +tqdm==4.66.1 # via feast (setup.py) typeguard==2.13.3 # via feast (setup.py) -typing-extensions==4.6.3 +types-protobuf==4.24.0.1 + # via mypy-protobuf +typing-extensions==4.7.1 # via + # fastapi # mypy # pydantic # sqlalchemy2-stubs -urllib3==2.0.2 + # uvicorn +urllib3==2.0.4 # via requests -uvicorn[standard]==0.22.0 +uvicorn[standard]==0.23.2 # via feast (setup.py) uvloop==0.17.0 # via uvicorn volatile==2.1.0 # via bowler -watchfiles==0.19.0 +watchfiles==0.20.0 # via uvicorn websockets==11.0.3 # via uvicorn -zipp==3.15.0 +zipp==3.16.2 # via importlib-metadata + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index de814374b68..9dfefc21081 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -8,7 +8,7 @@ adal==1.2.7 # via msrestazure adlfs==0.5.9 # via feast (setup.py) -aiohttp==3.8.4 +aiohttp==3.8.5 # via # adlfs # gcsfs @@ -18,7 +18,7 @@ alabaster==0.7.13 # via sphinx altair==4.2.0 # via great-expectations -anyio==3.7.0 +anyio==4.0.0 # via # httpcore # jupyter-server @@ -30,11 +30,8 @@ appnope==0.1.3 # via # ipykernel # ipython -argon2-cffi==21.3.0 - # via - # jupyter-server - # nbclassic - # notebook +argon2-cffi==23.1.0 + # via jupyter-server argon2-cffi-bindings==21.2.0 # via argon2-cffi arrow==1.2.3 @@ -45,9 +42,11 @@ asn1crypto==1.5.1 # snowflake-connector-python assertpy==1.1 # via feast (setup.py) -asttokens==2.2.1 +asttokens==2.4.0 # via stack-data -async-timeout==4.0.2 +async-lru==2.0.4 + # via jupyterlab +async-timeout==4.0.3 # via # aiohttp # redis @@ -56,9 +55,10 @@ attrs==23.1.0 # aiohttp # bowler # jsonschema + # referencing avro==1.10.0 # via feast (setup.py) -azure-core==1.27.0 +azure-core==1.29.3 # via # adlfs # azure-identity @@ -66,16 +66,18 @@ azure-core==1.27.0 # msrest azure-datalake-store==0.0.53 # via adlfs -azure-identity==1.13.0 +azure-identity==1.14.0 # via # adlfs # feast (setup.py) -azure-storage-blob==12.16.0 +azure-storage-blob==12.17.0 # via # adlfs # feast (setup.py) babel==2.12.1 - # via sphinx + # via + # jupyterlab-server + # sphinx backcall==0.2.0 # via ipython backports-zoneinfo==0.2.1 @@ -88,30 +90,30 @@ black==22.12.0 # via feast (setup.py) bleach==6.0.0 # via nbconvert -boto3==1.26.146 +boto3==1.28.42 # via # feast (setup.py) # moto -botocore==1.29.146 +botocore==1.31.42 # via # boto3 # moto # s3transfer bowler==0.9.0 # via feast (setup.py) -build==0.10.0 +build==1.0.3 # via # feast (setup.py) # pip-tools bytewax==0.15.1 # via feast (setup.py) -cachecontrol==0.13.0 +cachecontrol==0.13.1 # via firebase-admin cachetools==5.3.1 # via google-auth -cassandra-driver==3.27.0 +cassandra-driver==3.28.0 # via feast (setup.py) -certifi==2023.5.7 +certifi==2023.7.22 # via # httpcore # httpx @@ -126,14 +128,14 @@ cffi==1.15.1 # azure-datalake-store # cryptography # snowflake-connector-python -cfgv==3.3.1 +cfgv==3.4.0 # via pre-commit -charset-normalizer==3.1.0 +charset-normalizer==3.2.0 # via # aiohttp # requests # snowflake-connector-python -click==8.1.3 +click==8.1.7 # via # black # bowler @@ -150,16 +152,17 @@ colorama==0.4.6 # via # feast (setup.py) # great-expectations -comm==0.1.3 - # via ipykernel -coverage[toml]==7.2.7 +comm==0.1.4 + # via + # ipykernel + # ipywidgets +coverage[toml]==7.3.1 # via pytest-cov -cryptography==40.0.2 +cryptography==41.0.3 # via # adal # azure-identity # azure-storage-blob - # cassandra-driver # feast (setup.py) # great-expectations # moto @@ -173,7 +176,7 @@ dask==2023.5.0 # via feast (setup.py) db-dtypes==1.1.1 # via google-cloud-bigquery -debugpy==1.6.7 +debugpy==1.6.7.post1 # via ipykernel decorator==5.1.1 # via @@ -185,12 +188,12 @@ deprecated==1.2.14 # via redis deprecation==2.1.0 # via testcontainers -dill==0.3.6 +dill==0.3.7 # via # bytewax # feast (setup.py) # multiprocess -distlib==0.3.6 +distlib==0.3.7 # via virtualenv docker==6.1.3 # via @@ -200,23 +203,23 @@ docutils==0.19 # via sphinx entrypoints==0.4 # via altair -exceptiongroup==1.1.1 +exceptiongroup==1.1.3 # via # anyio # pytest -execnet==1.9.0 +execnet==2.0.2 # via pytest-xdist executing==1.2.0 # via stack-data -fastapi==0.95.2 +fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.1 +fastavro==1.8.2 # via # feast (setup.py) # pandavro -fastjsonschema==2.17.1 +fastjsonschema==2.18.0 # via nbformat -filelock==3.12.0 +filelock==3.12.3 # via # snowflake-connector-python # virtualenv @@ -228,7 +231,7 @@ flake8==6.0.0 # via feast (setup.py) fqdn==1.5.1 # via jsonschema -frozenlist==1.3.3 +frozenlist==1.4.0 # via # aiohttp # aiosignal @@ -243,7 +246,7 @@ geojson==2.5.0 # via rockset geomet==0.2.1.post1 # via cassandra-driver -google-api-core[grpc]==2.11.0 +google-api-core[grpc]==2.11.1 # via # feast (setup.py) # firebase-admin @@ -255,9 +258,9 @@ google-api-core[grpc]==2.11.0 # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.88.0 +google-api-python-client==2.98.0 # via firebase-admin -google-auth==2.19.1 +google-auth==2.22.0 # via # gcsfs # google-api-core @@ -271,35 +274,35 @@ google-auth-httplib2==0.1.0 # via google-api-python-client google-auth-oauthlib==1.0.0 # via gcsfs -google-cloud-bigquery[pandas]==3.11.0 +google-cloud-bigquery[pandas]==3.11.4 # via feast (setup.py) -google-cloud-bigquery-storage==2.20.0 +google-cloud-bigquery-storage==2.22.0 # via feast (setup.py) -google-cloud-bigtable==2.18.1 +google-cloud-bigtable==2.21.0 # via feast (setup.py) -google-cloud-core==2.3.2 +google-cloud-core==2.3.3 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-cloud-datastore==2.15.2 +google-cloud-datastore==2.18.0 # via feast (setup.py) google-cloud-firestore==2.11.1 # via firebase-admin -google-cloud-storage==2.9.0 +google-cloud-storage==2.10.0 # via # feast (setup.py) # firebase-admin # gcsfs google-crc32c==1.5.0 # via google-resumable-media -google-resumable-media==2.5.0 +google-resumable-media==2.6.0 # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.59.0 +googleapis-common-protos[grpc]==1.60.0 # via # feast (setup.py) # google-api-core @@ -307,30 +310,31 @@ googleapis-common-protos[grpc]==1.59.0 # grpcio-status great-expectations==0.15.50 # via feast (setup.py) -greenlet==2.0.2 - # via sqlalchemy grpc-google-iam-v1==0.12.6 # via google-cloud-bigtable -grpcio==1.54.2 +grpcio==1.57.0 # via # feast (setup.py) # google-api-core # google-cloud-bigquery # googleapis-common-protos # grpc-google-iam-v1 + # grpcio-health-checking # grpcio-reflection # grpcio-status # grpcio-testing # grpcio-tools -grpcio-reflection==1.54.2 +grpcio-health-checking==1.57.0 + # via feast (setup.py) +grpcio-reflection==1.57.0 # via feast (setup.py) -grpcio-status==1.54.2 +grpcio-status==1.57.0 # via google-api-core -grpcio-testing==1.54.2 +grpcio-testing==1.57.0 # via feast (setup.py) -grpcio-tools==1.54.2 +grpcio-tools==1.57.0 # via feast (setup.py) -gunicorn==20.1.0 +gunicorn==21.2.0 # via feast (setup.py) h11==0.14.0 # via @@ -338,21 +342,21 @@ h11==0.14.0 # uvicorn happybase==1.2.0 # via feast (setup.py) -hazelcast-python-client==5.2.0 +hazelcast-python-client==5.3.0 # via feast (setup.py) hiredis==2.2.3 # via feast (setup.py) -httpcore==0.17.2 +httpcore==0.17.3 # via httpx httplib2==0.22.0 # via # google-api-python-client # google-auth-httplib2 -httptools==0.5.0 +httptools==0.6.0 # via uvicorn httpx==0.24.1 # via feast (setup.py) -identify==2.5.24 +identify==2.5.27 # via pre-commit idna==3.4 # via @@ -364,32 +368,32 @@ idna==3.4 # yarl imagesize==1.4.1 # via sphinx -importlib-metadata==6.6.0 +importlib-metadata==6.8.0 # via + # build # dask # great-expectations # jupyter-client + # jupyter-lsp + # jupyterlab + # jupyterlab-server # nbconvert # sphinx -importlib-resources==5.12.0 - # via jsonschema +importlib-resources==6.0.1 + # via + # jsonschema + # jsonschema-specifications + # jupyterlab iniconfig==2.0.0 # via pytest -ipykernel==6.23.1 - # via - # ipywidgets - # nbclassic - # notebook +ipykernel==6.25.2 + # via jupyterlab ipython==8.12.2 # via # great-expectations # ipykernel # ipywidgets -ipython-genutils==0.2.0 - # via - # nbclassic - # notebook -ipywidgets==8.0.6 +ipywidgets==8.1.0 # via great-expectations isodate==0.6.1 # via @@ -399,7 +403,7 @@ isoduration==20.11.0 # via jsonschema isort==5.12.0 # via feast (setup.py) -jedi==0.18.2 +jedi==0.19.0 # via ipython jinja2==3.1.2 # via @@ -407,56 +411,69 @@ jinja2==3.1.2 # feast (setup.py) # great-expectations # jupyter-server + # jupyterlab + # jupyterlab-server # moto - # nbclassic # nbconvert - # notebook # sphinx jmespath==1.0.1 # via # boto3 # botocore -jsonpatch==1.32 +json5==0.9.14 + # via jupyterlab-server +jsonpatch==1.33 # via great-expectations -jsonpointer==2.3 +jsonpointer==2.4 # via # jsonpatch # jsonschema -jsonschema[format-nongpl]==4.17.3 +jsonschema[format-nongpl]==4.19.0 # via # altair # feast (setup.py) # great-expectations # jupyter-events + # jupyterlab-server # nbformat -jupyter-client==8.2.0 +jsonschema-specifications==2023.7.1 + # via jsonschema +jupyter-client==8.3.1 # via # ipykernel # jupyter-server - # nbclassic # nbclient - # notebook -jupyter-core==5.3.0 +jupyter-core==5.3.1 # via # ipykernel # jupyter-client # jupyter-server - # nbclassic + # jupyterlab # nbclient # nbconvert # nbformat - # notebook -jupyter-events==0.6.3 +jupyter-events==0.7.0 # via jupyter-server -jupyter-server==2.6.0 +jupyter-lsp==2.2.0 + # via jupyterlab +jupyter-server==2.7.3 # via - # nbclassic + # jupyter-lsp + # jupyterlab + # jupyterlab-server + # notebook # notebook-shim jupyter-server-terminals==0.4.4 # via jupyter-server +jupyterlab==4.0.5 + # via notebook jupyterlab-pygments==0.2.2 # via nbconvert -jupyterlab-widgets==3.0.7 +jupyterlab-server==2.24.0 + # via + # jupyterlab + # notebook +jupyterlab-widgets==3.0.8 # via ipywidgets kubernetes==20.13.0 # via feast (setup.py) @@ -469,7 +486,7 @@ markupsafe==2.1.3 # jinja2 # nbconvert # werkzeug -marshmallow==3.19.0 +marshmallow==3.20.1 # via great-expectations matplotlib-inline==0.1.6 # via @@ -479,19 +496,19 @@ mccabe==0.7.0 # via flake8 minio==7.1.0 # via feast (setup.py) -mistune==2.0.5 +mistune==3.0.1 # via # great-expectations # nbconvert -mmh3==4.0.0 +mmh3==4.0.1 # via feast (setup.py) mock==2.0.0 # via feast (setup.py) moreorless==0.4.0 # via bowler -moto==4.1.10 +moto==4.2.2 # via feast (setup.py) -msal==1.22.0 +msal==1.23.0 # via # azure-datalake-store # azure-identity @@ -508,7 +525,7 @@ multidict==6.0.4 # via # aiohttp # yarl -multiprocess==0.70.14 +multiprocess==0.70.15 # via bytewax mypy==0.982 # via @@ -520,37 +537,29 @@ mypy-extensions==1.0.0 # mypy mypy-protobuf==3.1 # via feast (setup.py) -mysqlclient==2.1.1 +mysqlclient==2.2.0 # via feast (setup.py) -nbclassic==1.0.0 - # via notebook nbclient==0.8.0 # via nbconvert -nbconvert==7.4.0 - # via - # jupyter-server - # nbclassic - # notebook -nbformat==5.9.0 +nbconvert==7.8.0 + # via jupyter-server +nbformat==5.9.2 # via # great-expectations # jupyter-server - # nbclassic # nbclient # nbconvert - # notebook -nest-asyncio==1.5.6 - # via - # ipykernel - # nbclassic - # notebook +nest-asyncio==1.5.7 + # via ipykernel nodeenv==1.8.0 # via pre-commit -notebook==6.5.4 +notebook==7.0.3 # via great-expectations notebook-shim==0.2.3 - # via nbclassic -numpy==1.24.3 + # via + # jupyterlab + # notebook +numpy==1.24.4 # via # altair # db-dtypes @@ -564,7 +573,7 @@ oauthlib==3.2.2 # via requests-oauthlib oscrypto==1.3.0 # via snowflake-connector-python -overrides==7.3.1 +overrides==7.4.0 # via jupyter-server packaging==23.1 # via @@ -575,8 +584,11 @@ packaging==23.1 # docker # google-cloud-bigquery # great-expectations + # gunicorn # ipykernel # jupyter-server + # jupyterlab + # jupyterlab-server # marshmallow # nbconvert # pytest @@ -600,7 +612,7 @@ parso==0.8.3 # via jedi partd==1.4.0 # via dask -pathspec==0.11.1 +pathspec==0.11.2 # via black pbr==5.11.1 # via mock @@ -608,31 +620,29 @@ pexpect==4.8.0 # via ipython pickleshare==0.7.5 # via ipython -pip-tools==6.13.0 +pip-tools==7.3.0 # via feast (setup.py) pkgutil-resolve-name==1.3.10 # via jsonschema -platformdirs==3.5.1 +platformdirs==3.8.1 # via # black # jupyter-core + # snowflake-connector-python # virtualenv -pluggy==1.0.0 +pluggy==1.3.0 # via pytest ply==3.11 # via thriftpy2 portalocker==2.7.0 # via msal-extensions -pre-commit==3.3.2 +pre-commit==3.3.1 # via feast (setup.py) -prometheus-client==0.17.0 - # via - # jupyter-server - # nbclassic - # notebook -prompt-toolkit==3.0.38 +prometheus-client==0.17.1 + # via jupyter-server +prompt-toolkit==3.0.39 # via ipython -proto-plus==1.22.2 +proto-plus==1.22.3 # via # feast (setup.py) # google-cloud-bigquery @@ -640,7 +650,7 @@ proto-plus==1.22.2 # google-cloud-bigtable # google-cloud-datastore # google-cloud-firestore -protobuf==4.23.2 +protobuf==4.23.3 # via # feast (setup.py) # google-api-core @@ -651,6 +661,7 @@ protobuf==4.23.2 # google-cloud-firestore # googleapis-common-protos # grpc-google-iam-v1 + # grpcio-health-checking # grpcio-reflection # grpcio-status # grpcio-testing @@ -661,7 +672,7 @@ psutil==5.9.0 # via # feast (setup.py) # ipykernel -psycopg2-binary==2.9.6 +psycopg2-binary==2.9.7 # via feast (setup.py) ptyprocess==0.7.0 # via @@ -695,43 +706,41 @@ pycparser==2.21 # via cffi pycryptodomex==3.18.0 # via snowflake-connector-python -pydantic==1.10.8 +pydantic==1.10.12 # via # fastapi # feast (setup.py) # great-expectations pyflakes==3.0.1 # via flake8 -pygments==2.15.1 +pygments==2.16.1 # via # feast (setup.py) # ipython # nbconvert # sphinx -pyjwt[crypto]==2.7.0 +pyjwt[crypto]==2.8.0 # via # adal # msal # snowflake-connector-python pymssql==2.2.8 # via feast (setup.py) -pymysql==1.0.3 +pymysql==1.1.0 # via feast (setup.py) pyodbc==4.0.39 # via feast (setup.py) pyopenssl==23.2.0 # via snowflake-connector-python -pyparsing==3.0.9 +pyparsing==3.1.1 # via # great-expectations # httplib2 pyproject-hooks==1.0.0 # via build -pyrsistent==0.19.3 - # via jsonschema -pyspark==3.4.0 +pyspark==3.4.1 # via feast (setup.py) -pytest==7.3.1 +pytest==7.4.1 # via # feast (setup.py) # pytest-benchmark @@ -772,7 +781,7 @@ python-dotenv==1.0.0 # via uvicorn python-json-logger==2.0.7 # via jupyter-events -pytz==2023.3 +pytz==2023.3.post1 # via # babel # great-expectations @@ -788,16 +797,19 @@ pyyaml==6.0.1 # pre-commit # responses # uvicorn -pyzmq==25.1.0 +pyzmq==25.1.1 # via # ipykernel # jupyter-client # jupyter-server - # nbclassic - # notebook redis==4.2.2 # via feast (setup.py) -regex==2023.5.5 +referencing==0.30.2 + # via + # jsonschema + # jsonschema-specifications + # jupyter-events +regex==2023.8.8 # via feast (setup.py) requests==2.31.0 # via @@ -813,6 +825,7 @@ requests==2.31.0 # google-cloud-bigquery # google-cloud-storage # great-expectations + # jupyterlab-server # kubernetes # moto # msal @@ -827,7 +840,7 @@ requests-oauthlib==1.3.1 # google-auth-oauthlib # kubernetes # msrest -responses==0.23.1 +responses==0.23.3 # via moto rfc3339-validator==0.1.4 # via @@ -837,28 +850,28 @@ rfc3986-validator==0.1.1 # via # jsonschema # jupyter-events -rockset==2.0.0 +rockset==2.1.0 # via feast (setup.py) +rpds-py==0.10.2 + # via + # jsonschema + # referencing rsa==4.9 # via google-auth ruamel-yaml==0.17.17 # via great-expectations ruamel-yaml-clib==0.2.7 # via ruamel-yaml -s3transfer==0.6.1 +s3transfer==0.6.2 # via boto3 scipy==1.10.1 # via great-expectations send2trash==1.8.2 - # via - # jupyter-server - # nbclassic - # notebook + # via jupyter-server six==1.16.0 # via # asttokens # azure-core - # azure-identity # bleach # cassandra-driver # geomet @@ -880,11 +893,11 @@ sniffio==1.3.0 # httpx snowballstemmer==2.2.0 # via sphinx -snowflake-connector-python[pandas]==3.0.4 +snowflake-connector-python[pandas]==3.1.1 # via feast (setup.py) sortedcontainers==2.4.0 # via snowflake-connector-python -soupsieve==2.4.1 +soupsieve==2.5 # via beautifulsoup4 sphinx==6.2.1 # via feast (setup.py) @@ -900,9 +913,9 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx -sqlalchemy[mypy]==1.4.48 +sqlalchemy[mypy]==1.4.49 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a34 +sqlalchemy2-stubs==0.0.2a35 # via sqlalchemy stack-data==0.6.2 # via ipython @@ -910,14 +923,12 @@ starlette==0.27.0 # via fastapi tabulate==0.9.0 # via feast (setup.py) -tenacity==8.2.2 +tenacity==8.2.3 # via feast (setup.py) terminado==0.17.1 # via # jupyter-server # jupyter-server-terminals - # nbclassic - # notebook testcontainers==3.7.1 # via feast (setup.py) thriftpy2==0.4.16 @@ -931,23 +942,27 @@ tomli==2.0.1 # black # build # coverage + # jupyterlab # mypy + # pip-tools # pyproject-hooks # pytest +tomlkit==0.12.1 + # via snowflake-connector-python toolz==0.12.0 # via # altair # dask # partd -tornado==6.3.2 +tornado==6.3.3 # via # ipykernel # jupyter-client # jupyter-server - # nbclassic + # jupyterlab # notebook # terminado -tqdm==4.65.0 +tqdm==4.66.1 # via # feast (setup.py) # great-expectations @@ -961,12 +976,11 @@ traitlets==5.9.0 # jupyter-core # jupyter-events # jupyter-server + # jupyterlab # matplotlib-inline - # nbclassic # nbclient # nbconvert # nbformat - # notebook trino==0.326.0 # via feast (setup.py) typeguard==2.13.3 @@ -975,33 +989,36 @@ types-protobuf==3.19.22 # via # feast (setup.py) # mypy-protobuf -types-pymysql==1.0.19.7 +types-pymysql==1.1.0.1 # via feast (setup.py) -types-pyopenssl==23.2.0.0 +types-pyopenssl==23.2.0.2 # via types-redis -types-python-dateutil==2.8.19.13 +types-python-dateutil==2.8.19.14 # via feast (setup.py) -types-pytz==2023.3.0.0 +types-pytz==2023.3.0.1 # via feast (setup.py) -types-pyyaml==6.0.12.10 +types-pyyaml==6.0.12.11 # via # feast (setup.py) # responses -types-redis==4.5.5.2 +types-redis==4.6.0.5 # via feast (setup.py) -types-requests==2.31.0.1 +types-requests==2.31.0.2 # via feast (setup.py) -types-setuptools==67.8.0.0 +types-setuptools==68.2.0.0 # via feast (setup.py) -types-tabulate==0.9.0.2 +types-tabulate==0.9.0.3 # via feast (setup.py) -types-urllib3==1.26.25.13 +types-urllib3==1.26.25.14 # via types-requests -typing-extensions==4.6.3 +typing-extensions==4.7.1 # via + # async-lru # azure-core # azure-storage-blob # black + # fastapi + # filelock # great-expectations # ipython # mypy @@ -1009,11 +1026,12 @@ typing-extensions==4.6.3 # snowflake-connector-python # sqlalchemy2-stubs # starlette + # uvicorn tzlocal==5.0.1 # via # great-expectations # trino -uri-template==1.2.0 +uri-template==1.3.0 # via jsonschema uritemplate==4.1.1 # via google-api-python-client @@ -1030,15 +1048,17 @@ urllib3==1.26.16 # responses # rockset # snowflake-connector-python -uvicorn[standard]==0.22.0 +uvicorn[standard]==0.23.2 # via feast (setup.py) uvloop==0.17.0 # via uvicorn virtualenv==20.23.0 - # via pre-commit + # via + # feast (setup.py) + # pre-commit volatile==2.1.0 # via bowler -watchfiles==0.19.0 +watchfiles==0.20.0 # via uvicorn wcwidth==0.2.6 # via prompt-toolkit @@ -1048,18 +1068,18 @@ webencodings==0.5.1 # via # bleach # tinycss2 -websocket-client==1.5.2 +websocket-client==1.6.2 # via # docker # jupyter-server # kubernetes websockets==11.0.3 # via uvicorn -werkzeug==2.3.4 +werkzeug==2.3.7 # via moto -wheel==0.40.0 +wheel==0.41.2 # via pip-tools -widgetsnbextension==4.0.7 +widgetsnbextension==4.0.8 # via ipywidgets wrapt==1.15.0 # via @@ -1069,7 +1089,7 @@ xmltodict==0.13.0 # via moto yarl==1.9.2 # via aiohttp -zipp==3.15.0 +zipp==3.16.2 # via # importlib-metadata # importlib-resources diff --git a/sdk/python/requirements/py3.8-requirements.txt b/sdk/python/requirements/py3.8-requirements.txt index 55ee6349048..636f886133d 100644 --- a/sdk/python/requirements/py3.8-requirements.txt +++ b/sdk/python/requirements/py3.8-requirements.txt @@ -4,7 +4,7 @@ # # pip-compile --output-file=sdk/python/requirements/py3.8-requirements.txt # -anyio==3.7.0 +anyio==4.0.0 # via # httpcore # starlette @@ -15,16 +15,17 @@ attrs==23.1.0 # via # bowler # jsonschema + # referencing bowler==0.9.0 # via feast (setup.py) -certifi==2023.5.7 +certifi==2023.7.22 # via # httpcore # httpx # requests -charset-normalizer==3.1.0 +charset-normalizer==3.2.0 # via requests -click==8.1.3 +click==8.1.7 # via # bowler # dask @@ -37,37 +38,41 @@ colorama==0.4.6 # via feast (setup.py) dask==2023.5.0 # via feast (setup.py) -dill==0.3.6 +dill==0.3.7 # via feast (setup.py) -exceptiongroup==1.1.1 +exceptiongroup==1.1.3 # via anyio -fastapi==0.95.2 +fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.1 +fastavro==1.8.2 # via # feast (setup.py) # pandavro fissix==21.11.13 # via bowler -fsspec==2023.5.0 +fsspec==2023.9.0 # via dask -greenlet==2.0.2 - # via sqlalchemy -grpcio==1.54.2 +grpcio==1.57.0 # via # feast (setup.py) + # grpcio-health-checking # grpcio-reflection -grpcio-reflection==1.54.2 + # grpcio-tools +grpcio-health-checking==1.57.0 + # via feast (setup.py) +grpcio-reflection==1.57.0 + # via feast (setup.py) +grpcio-tools==1.57.0 # via feast (setup.py) -gunicorn==20.1.0 +gunicorn==21.2.0 # via feast (setup.py) h11==0.14.0 # via # httpcore # uvicorn -httpcore==0.17.2 +httpcore==0.17.3 # via httpx -httptools==0.5.0 +httptools==0.6.0 # via uvicorn httpx==0.24.1 # via feast (setup.py) @@ -76,34 +81,42 @@ idna==3.4 # anyio # httpx # requests -importlib-metadata==6.6.0 +importlib-metadata==6.8.0 # via dask -importlib-resources==5.12.0 - # via jsonschema +importlib-resources==6.0.1 + # via + # jsonschema + # jsonschema-specifications jinja2==3.1.2 # via feast (setup.py) -jsonschema==4.17.3 +jsonschema==4.19.0 # via feast (setup.py) +jsonschema-specifications==2023.7.1 + # via jsonschema locket==1.0.0 # via partd markupsafe==2.1.3 # via jinja2 -mmh3==4.0.0 +mmh3==4.0.1 # via feast (setup.py) moreorless==0.4.0 # via bowler -mypy==1.3.0 +mypy==1.5.1 # via sqlalchemy mypy-extensions==1.0.0 # via mypy -numpy==1.24.3 +mypy-protobuf==3.1 + # via feast (setup.py) +numpy==1.24.4 # via # feast (setup.py) # pandas # pandavro # pyarrow packaging==23.1 - # via dask + # via + # dask + # gunicorn pandas==1.5.3 # via # feast (setup.py) @@ -114,36 +127,45 @@ partd==1.4.0 # via dask pkgutil-resolve-name==1.3.10 # via jsonschema -proto-plus==1.22.2 +proto-plus==1.22.3 # via feast (setup.py) -protobuf==4.23.2 +protobuf==4.23.3 # via # feast (setup.py) + # grpcio-health-checking # grpcio-reflection + # grpcio-tools + # mypy-protobuf # proto-plus pyarrow==11.0.0 # via feast (setup.py) -pydantic==1.10.8 +pydantic==1.10.12 # via # fastapi # feast (setup.py) -pygments==2.15.1 +pygments==2.16.1 # via feast (setup.py) -pyrsistent==0.19.3 - # via jsonschema python-dateutil==2.8.2 # via pandas python-dotenv==1.0.0 # via uvicorn -pytz==2023.3 +pytz==2023.3.post1 # via pandas pyyaml==6.0.1 # via # dask # feast (setup.py) # uvicorn +referencing==0.30.2 + # via + # jsonschema + # jsonschema-specifications requests==2.31.0 # via feast (setup.py) +rpds-py==0.10.2 + # via + # jsonschema + # referencing six==1.16.0 # via # pandavro @@ -153,15 +175,15 @@ sniffio==1.3.0 # anyio # httpcore # httpx -sqlalchemy[mypy]==1.4.48 +sqlalchemy[mypy]==1.4.49 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a34 +sqlalchemy2-stubs==0.0.2a35 # via sqlalchemy starlette==0.27.0 # via fastapi tabulate==0.9.0 # via feast (setup.py) -tenacity==8.2.2 +tenacity==8.2.3 # via feast (setup.py) toml==0.10.2 # via feast (setup.py) @@ -171,29 +193,36 @@ toolz==0.12.0 # via # dask # partd -tqdm==4.65.0 +tqdm==4.66.1 # via feast (setup.py) typeguard==2.13.3 # via feast (setup.py) -typing-extensions==4.6.3 +types-protobuf==4.24.0.1 + # via mypy-protobuf +typing-extensions==4.7.1 # via + # fastapi # mypy # pydantic # sqlalchemy2-stubs # starlette -urllib3==2.0.2 + # uvicorn +urllib3==2.0.4 # via requests -uvicorn[standard]==0.22.0 +uvicorn[standard]==0.23.2 # via feast (setup.py) uvloop==0.17.0 # via uvicorn volatile==2.1.0 # via bowler -watchfiles==0.19.0 +watchfiles==0.20.0 # via uvicorn websockets==11.0.3 # via uvicorn -zipp==3.15.0 +zipp==3.16.2 # via # importlib-metadata # importlib-resources + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index aa79b8ec3be..3992303d00e 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -1,6 +1,6 @@ # -# This file is autogenerated by pip-compile with python 3.9 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: # # pip-compile --extra=ci --output-file=sdk/python/requirements/py3.9-ci-requirements.txt # @@ -8,7 +8,7 @@ adal==1.2.7 # via msrestazure adlfs==0.5.9 # via feast (setup.py) -aiohttp==3.8.4 +aiohttp==3.8.5 # via # adlfs # gcsfs @@ -18,7 +18,7 @@ alabaster==0.7.13 # via sphinx altair==4.2.0 # via great-expectations -anyio==3.7.0 +anyio==4.0.0 # via # httpcore # jupyter-server @@ -30,11 +30,8 @@ appnope==0.1.3 # via # ipykernel # ipython -argon2-cffi==21.3.0 - # via - # jupyter-server - # nbclassic - # notebook +argon2-cffi==23.1.0 + # via jupyter-server argon2-cffi-bindings==21.2.0 # via argon2-cffi arrow==1.2.3 @@ -45,9 +42,11 @@ asn1crypto==1.5.1 # snowflake-connector-python assertpy==1.1 # via feast (setup.py) -asttokens==2.2.1 +asttokens==2.4.0 # via stack-data -async-timeout==4.0.2 +async-lru==2.0.4 + # via jupyterlab +async-timeout==4.0.3 # via # aiohttp # redis @@ -56,9 +55,10 @@ attrs==23.1.0 # aiohttp # bowler # jsonschema + # referencing avro==1.10.0 # via feast (setup.py) -azure-core==1.27.0 +azure-core==1.29.3 # via # adlfs # azure-identity @@ -66,16 +66,18 @@ azure-core==1.27.0 # msrest azure-datalake-store==0.0.53 # via adlfs -azure-identity==1.13.0 +azure-identity==1.14.0 # via # adlfs # feast (setup.py) -azure-storage-blob==12.16.0 +azure-storage-blob==12.17.0 # via # adlfs # feast (setup.py) babel==2.12.1 - # via sphinx + # via + # jupyterlab-server + # sphinx backcall==0.2.0 # via ipython beautifulsoup4==4.12.2 @@ -84,30 +86,30 @@ black==22.12.0 # via feast (setup.py) bleach==6.0.0 # via nbconvert -boto3==1.26.146 +boto3==1.28.42 # via # feast (setup.py) # moto -botocore==1.29.146 +botocore==1.31.42 # via # boto3 # moto # s3transfer bowler==0.9.0 # via feast (setup.py) -build==0.10.0 +build==1.0.3 # via # feast (setup.py) # pip-tools bytewax==0.15.1 # via feast (setup.py) -cachecontrol==0.13.0 +cachecontrol==0.13.1 # via firebase-admin cachetools==5.3.1 # via google-auth -cassandra-driver==3.27.0 +cassandra-driver==3.28.0 # via feast (setup.py) -certifi==2023.5.7 +certifi==2023.7.22 # via # httpcore # httpx @@ -122,14 +124,14 @@ cffi==1.15.1 # azure-datalake-store # cryptography # snowflake-connector-python -cfgv==3.3.1 +cfgv==3.4.0 # via pre-commit -charset-normalizer==3.1.0 +charset-normalizer==3.2.0 # via # aiohttp # requests # snowflake-connector-python -click==8.1.3 +click==8.1.7 # via # black # bowler @@ -146,16 +148,17 @@ colorama==0.4.6 # via # feast (setup.py) # great-expectations -comm==0.1.3 - # via ipykernel -coverage[toml]==7.2.7 +comm==0.1.4 + # via + # ipykernel + # ipywidgets +coverage[toml]==7.3.1 # via pytest-cov -cryptography==40.0.2 +cryptography==41.0.3 # via # adal # azure-identity # azure-storage-blob - # cassandra-driver # feast (setup.py) # great-expectations # moto @@ -165,11 +168,11 @@ cryptography==40.0.2 # snowflake-connector-python # types-pyopenssl # types-redis -dask==2023.5.1 +dask==2023.9.1 # via feast (setup.py) db-dtypes==1.1.1 # via google-cloud-bigquery -debugpy==1.6.7 +debugpy==1.6.7.post1 # via ipykernel decorator==5.1.1 # via @@ -181,12 +184,12 @@ deprecated==1.2.14 # via redis deprecation==2.1.0 # via testcontainers -dill==0.3.6 +dill==0.3.7 # via # bytewax # feast (setup.py) # multiprocess -distlib==0.3.6 +distlib==0.3.7 # via virtualenv docker==6.1.3 # via @@ -196,23 +199,24 @@ docutils==0.19 # via sphinx entrypoints==0.4 # via altair -exceptiongroup==1.1.1 +exceptiongroup==1.1.3 # via # anyio + # ipython # pytest -execnet==1.9.0 +execnet==2.0.2 # via pytest-xdist executing==1.2.0 # via stack-data -fastapi==0.95.2 +fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.1 +fastavro==1.8.2 # via # feast (setup.py) # pandavro -fastjsonschema==2.17.1 +fastjsonschema==2.18.0 # via nbformat -filelock==3.12.0 +filelock==3.12.3 # via # snowflake-connector-python # virtualenv @@ -224,7 +228,7 @@ flake8==6.0.0 # via feast (setup.py) fqdn==1.5.1 # via jsonschema -frozenlist==1.3.3 +frozenlist==1.4.0 # via # aiohttp # aiosignal @@ -239,7 +243,7 @@ geojson==2.5.0 # via rockset geomet==0.2.1.post1 # via cassandra-driver -google-api-core[grpc]==2.11.0 +google-api-core[grpc]==2.11.1 # via # feast (setup.py) # firebase-admin @@ -251,9 +255,9 @@ google-api-core[grpc]==2.11.0 # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.88.0 +google-api-python-client==2.98.0 # via firebase-admin -google-auth==2.19.1 +google-auth==2.22.0 # via # gcsfs # google-api-core @@ -267,35 +271,35 @@ google-auth-httplib2==0.1.0 # via google-api-python-client google-auth-oauthlib==1.0.0 # via gcsfs -google-cloud-bigquery[pandas]==3.11.0 +google-cloud-bigquery[pandas]==3.11.4 # via feast (setup.py) -google-cloud-bigquery-storage==2.20.0 +google-cloud-bigquery-storage==2.22.0 # via feast (setup.py) -google-cloud-bigtable==2.18.1 +google-cloud-bigtable==2.21.0 # via feast (setup.py) -google-cloud-core==2.3.2 +google-cloud-core==2.3.3 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-cloud-datastore==2.15.2 +google-cloud-datastore==2.18.0 # via feast (setup.py) google-cloud-firestore==2.11.1 # via firebase-admin -google-cloud-storage==2.9.0 +google-cloud-storage==2.10.0 # via # feast (setup.py) # firebase-admin # gcsfs google-crc32c==1.5.0 # via google-resumable-media -google-resumable-media==2.5.0 +google-resumable-media==2.6.0 # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.59.0 +googleapis-common-protos[grpc]==1.60.0 # via # feast (setup.py) # google-api-core @@ -303,30 +307,31 @@ googleapis-common-protos[grpc]==1.59.0 # grpcio-status great-expectations==0.15.50 # via feast (setup.py) -greenlet==2.0.2 - # via sqlalchemy grpc-google-iam-v1==0.12.6 # via google-cloud-bigtable -grpcio==1.54.2 +grpcio==1.57.0 # via # feast (setup.py) # google-api-core # google-cloud-bigquery # googleapis-common-protos # grpc-google-iam-v1 + # grpcio-health-checking # grpcio-reflection # grpcio-status # grpcio-testing # grpcio-tools -grpcio-reflection==1.54.2 +grpcio-health-checking==1.57.0 # via feast (setup.py) -grpcio-status==1.54.2 +grpcio-reflection==1.57.0 + # via feast (setup.py) +grpcio-status==1.57.0 # via google-api-core -grpcio-testing==1.54.2 +grpcio-testing==1.57.0 # via feast (setup.py) -grpcio-tools==1.54.2 +grpcio-tools==1.57.0 # via feast (setup.py) -gunicorn==20.1.0 +gunicorn==21.2.0 # via feast (setup.py) h11==0.14.0 # via @@ -334,21 +339,21 @@ h11==0.14.0 # uvicorn happybase==1.2.0 # via feast (setup.py) -hazelcast-python-client==5.2.0 +hazelcast-python-client==5.3.0 # via feast (setup.py) hiredis==2.2.3 # via feast (setup.py) -httpcore==0.17.2 +httpcore==0.17.3 # via httpx httplib2==0.22.0 # via # google-api-python-client # google-auth-httplib2 -httptools==0.5.0 +httptools==0.6.0 # via uvicorn httpx==0.24.1 # via feast (setup.py) -identify==2.5.24 +identify==2.5.27 # via pre-commit idna==3.4 # via @@ -360,30 +365,27 @@ idna==3.4 # yarl imagesize==1.4.1 # via sphinx -importlib-metadata==6.6.0 +importlib-metadata==6.8.0 # via + # build # dask # great-expectations # jupyter-client + # jupyter-lsp + # jupyterlab + # jupyterlab-server # nbconvert # sphinx iniconfig==2.0.0 # via pytest -ipykernel==6.23.1 - # via - # ipywidgets - # nbclassic - # notebook -ipython==8.14.0 +ipykernel==6.25.2 + # via jupyterlab +ipython==8.15.0 # via # great-expectations # ipykernel # ipywidgets -ipython-genutils==0.2.0 - # via - # nbclassic - # notebook -ipywidgets==8.0.6 +ipywidgets==8.1.0 # via great-expectations isodate==0.6.1 # via @@ -393,7 +395,7 @@ isoduration==20.11.0 # via jsonschema isort==5.12.0 # via feast (setup.py) -jedi==0.18.2 +jedi==0.19.0 # via ipython jinja2==3.1.2 # via @@ -401,56 +403,69 @@ jinja2==3.1.2 # feast (setup.py) # great-expectations # jupyter-server + # jupyterlab + # jupyterlab-server # moto - # nbclassic # nbconvert - # notebook # sphinx jmespath==1.0.1 # via # boto3 # botocore -jsonpatch==1.32 +json5==0.9.14 + # via jupyterlab-server +jsonpatch==1.33 # via great-expectations -jsonpointer==2.3 +jsonpointer==2.4 # via # jsonpatch # jsonschema -jsonschema[format-nongpl]==4.17.3 +jsonschema[format-nongpl]==4.19.0 # via # altair # feast (setup.py) # great-expectations # jupyter-events + # jupyterlab-server # nbformat -jupyter-client==8.2.0 +jsonschema-specifications==2023.7.1 + # via jsonschema +jupyter-client==8.3.1 # via # ipykernel # jupyter-server - # nbclassic # nbclient - # notebook -jupyter-core==5.3.0 +jupyter-core==5.3.1 # via # ipykernel # jupyter-client # jupyter-server - # nbclassic + # jupyterlab # nbclient # nbconvert # nbformat - # notebook -jupyter-events==0.6.3 +jupyter-events==0.7.0 # via jupyter-server -jupyter-server==2.6.0 +jupyter-lsp==2.2.0 + # via jupyterlab +jupyter-server==2.7.3 # via - # nbclassic + # jupyter-lsp + # jupyterlab + # jupyterlab-server + # notebook # notebook-shim jupyter-server-terminals==0.4.4 # via jupyter-server +jupyterlab==4.0.5 + # via notebook jupyterlab-pygments==0.2.2 # via nbconvert -jupyterlab-widgets==3.0.7 +jupyterlab-server==2.24.0 + # via + # jupyterlab + # notebook +jupyterlab-widgets==3.0.8 # via ipywidgets kubernetes==20.13.0 # via feast (setup.py) @@ -463,7 +478,7 @@ markupsafe==2.1.3 # jinja2 # nbconvert # werkzeug -marshmallow==3.19.0 +marshmallow==3.20.1 # via great-expectations matplotlib-inline==0.1.6 # via @@ -473,19 +488,19 @@ mccabe==0.7.0 # via flake8 minio==7.1.0 # via feast (setup.py) -mistune==2.0.5 +mistune==3.0.1 # via # great-expectations # nbconvert -mmh3==4.0.0 +mmh3==4.0.1 # via feast (setup.py) mock==2.0.0 # via feast (setup.py) moreorless==0.4.0 # via bowler -moto==4.1.10 +moto==4.2.2 # via feast (setup.py) -msal==1.22.0 +msal==1.23.0 # via # azure-datalake-store # azure-identity @@ -502,7 +517,7 @@ multidict==6.0.4 # via # aiohttp # yarl -multiprocess==0.70.14 +multiprocess==0.70.15 # via bytewax mypy==0.982 # via @@ -514,37 +529,29 @@ mypy-extensions==1.0.0 # mypy mypy-protobuf==3.1 # via feast (setup.py) -mysqlclient==2.1.1 +mysqlclient==2.2.0 # via feast (setup.py) -nbclassic==1.0.0 - # via notebook nbclient==0.8.0 # via nbconvert -nbconvert==7.4.0 - # via - # jupyter-server - # nbclassic - # notebook -nbformat==5.9.0 +nbconvert==7.8.0 + # via jupyter-server +nbformat==5.9.2 # via # great-expectations # jupyter-server - # nbclassic # nbclient # nbconvert - # notebook -nest-asyncio==1.5.6 - # via - # ipykernel - # nbclassic - # notebook +nest-asyncio==1.5.7 + # via ipykernel nodeenv==1.8.0 # via pre-commit -notebook==6.5.4 +notebook==7.0.3 # via great-expectations notebook-shim==0.2.3 - # via nbclassic -numpy==1.24.3 + # via + # jupyterlab + # notebook +numpy==1.25.2 # via # altair # db-dtypes @@ -558,7 +565,7 @@ oauthlib==3.2.2 # via requests-oauthlib oscrypto==1.3.0 # via snowflake-connector-python -overrides==7.3.1 +overrides==7.4.0 # via jupyter-server packaging==23.1 # via @@ -569,8 +576,11 @@ packaging==23.1 # docker # google-cloud-bigquery # great-expectations + # gunicorn # ipykernel # jupyter-server + # jupyterlab + # jupyterlab-server # marshmallow # nbconvert # pytest @@ -594,7 +604,7 @@ parso==0.8.3 # via jedi partd==1.4.0 # via dask -pathspec==0.11.1 +pathspec==0.11.2 # via black pbr==5.11.1 # via mock @@ -602,29 +612,27 @@ pexpect==4.8.0 # via ipython pickleshare==0.7.5 # via ipython -pip-tools==6.13.0 +pip-tools==7.3.0 # via feast (setup.py) -platformdirs==3.5.1 +platformdirs==3.8.1 # via # black # jupyter-core + # snowflake-connector-python # virtualenv -pluggy==1.0.0 +pluggy==1.3.0 # via pytest ply==3.11 # via thriftpy2 portalocker==2.7.0 # via msal-extensions -pre-commit==3.3.2 +pre-commit==3.3.1 # via feast (setup.py) -prometheus-client==0.17.0 - # via - # jupyter-server - # nbclassic - # notebook -prompt-toolkit==3.0.38 +prometheus-client==0.17.1 + # via jupyter-server +prompt-toolkit==3.0.39 # via ipython -proto-plus==1.22.2 +proto-plus==1.22.3 # via # feast (setup.py) # google-cloud-bigquery @@ -632,7 +640,7 @@ proto-plus==1.22.2 # google-cloud-bigtable # google-cloud-datastore # google-cloud-firestore -protobuf==4.23.2 +protobuf==4.23.3 # via # feast (setup.py) # google-api-core @@ -643,6 +651,7 @@ protobuf==4.23.2 # google-cloud-firestore # googleapis-common-protos # grpc-google-iam-v1 + # grpcio-health-checking # grpcio-reflection # grpcio-status # grpcio-testing @@ -653,7 +662,7 @@ psutil==5.9.0 # via # feast (setup.py) # ipykernel -psycopg2-binary==2.9.6 +psycopg2-binary==2.9.7 # via feast (setup.py) ptyprocess==0.7.0 # via @@ -687,43 +696,41 @@ pycparser==2.21 # via cffi pycryptodomex==3.18.0 # via snowflake-connector-python -pydantic==1.10.8 +pydantic==1.10.12 # via # fastapi # feast (setup.py) # great-expectations pyflakes==3.0.1 # via flake8 -pygments==2.15.1 +pygments==2.16.1 # via # feast (setup.py) # ipython # nbconvert # sphinx -pyjwt[crypto]==2.7.0 +pyjwt[crypto]==2.8.0 # via # adal # msal # snowflake-connector-python pymssql==2.2.8 # via feast (setup.py) -pymysql==1.0.3 +pymysql==1.1.0 # via feast (setup.py) pyodbc==4.0.39 # via feast (setup.py) pyopenssl==23.2.0 # via snowflake-connector-python -pyparsing==3.0.9 +pyparsing==3.1.1 # via # great-expectations # httplib2 pyproject-hooks==1.0.0 # via build -pyrsistent==0.19.3 - # via jsonschema -pyspark==3.4.0 +pyspark==3.4.1 # via feast (setup.py) -pytest==7.3.1 +pytest==7.4.1 # via # feast (setup.py) # pytest-benchmark @@ -764,7 +771,7 @@ python-dotenv==1.0.0 # via uvicorn python-json-logger==2.0.7 # via jupyter-events -pytz==2023.3 +pytz==2023.3.post1 # via # great-expectations # pandas @@ -779,16 +786,19 @@ pyyaml==6.0.1 # pre-commit # responses # uvicorn -pyzmq==25.1.0 +pyzmq==25.1.1 # via # ipykernel # jupyter-client # jupyter-server - # nbclassic - # notebook redis==4.2.2 # via feast (setup.py) -regex==2023.5.5 +referencing==0.30.2 + # via + # jsonschema + # jsonschema-specifications + # jupyter-events +regex==2023.8.8 # via feast (setup.py) requests==2.31.0 # via @@ -804,6 +814,7 @@ requests==2.31.0 # google-cloud-bigquery # google-cloud-storage # great-expectations + # jupyterlab-server # kubernetes # moto # msal @@ -818,7 +829,7 @@ requests-oauthlib==1.3.1 # google-auth-oauthlib # kubernetes # msrest -responses==0.23.1 +responses==0.23.3 # via moto rfc3339-validator==0.1.4 # via @@ -828,28 +839,28 @@ rfc3986-validator==0.1.1 # via # jsonschema # jupyter-events -rockset==2.0.0 +rockset==2.1.0 # via feast (setup.py) +rpds-py==0.10.2 + # via + # jsonschema + # referencing rsa==4.9 # via google-auth ruamel-yaml==0.17.17 # via great-expectations ruamel-yaml-clib==0.2.7 # via ruamel-yaml -s3transfer==0.6.1 +s3transfer==0.6.2 # via boto3 -scipy==1.10.1 +scipy==1.11.2 # via great-expectations send2trash==1.8.2 - # via - # jupyter-server - # nbclassic - # notebook + # via jupyter-server six==1.16.0 # via # asttokens # azure-core - # azure-identity # bleach # cassandra-driver # geomet @@ -871,29 +882,35 @@ sniffio==1.3.0 # httpx snowballstemmer==2.2.0 # via sphinx -snowflake-connector-python[pandas]==3.0.4 +snowflake-connector-python[pandas]==3.1.1 # via feast (setup.py) sortedcontainers==2.4.0 # via snowflake-connector-python -soupsieve==2.4.1 +soupsieve==2.5 # via beautifulsoup4 sphinx==6.2.1 - # via feast (setup.py) -sphinxcontrib-applehelp==1.0.4 + # via + # feast (setup.py) + # sphinxcontrib-applehelp + # sphinxcontrib-devhelp + # sphinxcontrib-htmlhelp + # sphinxcontrib-qthelp + # sphinxcontrib-serializinghtml +sphinxcontrib-applehelp==1.0.7 # via sphinx -sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-devhelp==1.0.5 # via sphinx -sphinxcontrib-htmlhelp==2.0.1 +sphinxcontrib-htmlhelp==2.0.4 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-qthelp==1.0.6 # via sphinx -sphinxcontrib-serializinghtml==1.1.5 +sphinxcontrib-serializinghtml==1.1.9 # via sphinx -sqlalchemy[mypy]==1.4.48 +sqlalchemy[mypy]==1.4.49 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a34 +sqlalchemy2-stubs==0.0.2a35 # via sqlalchemy stack-data==0.6.2 # via ipython @@ -901,14 +918,12 @@ starlette==0.27.0 # via fastapi tabulate==0.9.0 # via feast (setup.py) -tenacity==8.2.2 +tenacity==8.2.3 # via feast (setup.py) terminado==0.17.1 # via # jupyter-server # jupyter-server-terminals - # nbclassic - # notebook testcontainers==3.7.1 # via feast (setup.py) thriftpy2==0.4.16 @@ -922,23 +937,27 @@ tomli==2.0.1 # black # build # coverage + # jupyterlab # mypy + # pip-tools # pyproject-hooks # pytest +tomlkit==0.12.1 + # via snowflake-connector-python toolz==0.12.0 # via # altair # dask # partd -tornado==6.3.2 +tornado==6.3.3 # via # ipykernel # jupyter-client # jupyter-server - # nbclassic + # jupyterlab # notebook # terminado -tqdm==4.65.0 +tqdm==4.66.1 # via # feast (setup.py) # great-expectations @@ -952,12 +971,11 @@ traitlets==5.9.0 # jupyter-core # jupyter-events # jupyter-server + # jupyterlab # matplotlib-inline - # nbclassic # nbclient # nbconvert # nbformat - # notebook trino==0.326.0 # via feast (setup.py) typeguard==2.13.3 @@ -966,33 +984,36 @@ types-protobuf==3.19.22 # via # feast (setup.py) # mypy-protobuf -types-pymysql==1.0.19.7 +types-pymysql==1.1.0.1 # via feast (setup.py) -types-pyopenssl==23.2.0.0 +types-pyopenssl==23.2.0.2 # via types-redis -types-python-dateutil==2.8.19.13 +types-python-dateutil==2.8.19.14 # via feast (setup.py) -types-pytz==2023.3.0.0 +types-pytz==2023.3.0.1 # via feast (setup.py) -types-pyyaml==6.0.12.10 +types-pyyaml==6.0.12.11 # via # feast (setup.py) # responses -types-redis==4.5.5.2 +types-redis==4.6.0.5 # via feast (setup.py) -types-requests==2.31.0.1 +types-requests==2.31.0.2 # via feast (setup.py) -types-setuptools==67.8.0.0 +types-setuptools==68.2.0.0 # via feast (setup.py) -types-tabulate==0.9.0.2 +types-tabulate==0.9.0.3 # via feast (setup.py) -types-urllib3==1.26.25.13 +types-urllib3==1.26.25.14 # via types-requests -typing-extensions==4.6.3 +typing-extensions==4.7.1 # via + # async-lru # azure-core # azure-storage-blob # black + # fastapi + # filelock # great-expectations # ipython # mypy @@ -1000,11 +1021,12 @@ typing-extensions==4.6.3 # snowflake-connector-python # sqlalchemy2-stubs # starlette + # uvicorn tzlocal==5.0.1 # via # great-expectations # trino -uri-template==1.2.0 +uri-template==1.3.0 # via jsonschema uritemplate==4.1.1 # via google-api-python-client @@ -1021,15 +1043,17 @@ urllib3==1.26.16 # responses # rockset # snowflake-connector-python -uvicorn[standard]==0.22.0 +uvicorn[standard]==0.23.2 # via feast (setup.py) uvloop==0.17.0 # via uvicorn virtualenv==20.23.0 - # via pre-commit + # via + # feast (setup.py) + # pre-commit volatile==2.1.0 # via bowler -watchfiles==0.19.0 +watchfiles==0.20.0 # via uvicorn wcwidth==0.2.6 # via prompt-toolkit @@ -1039,18 +1063,18 @@ webencodings==0.5.1 # via # bleach # tinycss2 -websocket-client==1.5.2 +websocket-client==1.6.2 # via # docker # jupyter-server # kubernetes websockets==11.0.3 # via uvicorn -werkzeug==2.3.4 +werkzeug==2.3.7 # via moto -wheel==0.40.0 +wheel==0.41.2 # via pip-tools -widgetsnbextension==4.0.7 +widgetsnbextension==4.0.8 # via ipywidgets wrapt==1.15.0 # via @@ -1060,7 +1084,7 @@ xmltodict==0.13.0 # via moto yarl==1.9.2 # via aiohttp -zipp==3.15.0 +zipp==3.16.2 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: diff --git a/sdk/python/requirements/py3.9-requirements.txt b/sdk/python/requirements/py3.9-requirements.txt index 53b0ff0e584..7d30fd3452b 100644 --- a/sdk/python/requirements/py3.9-requirements.txt +++ b/sdk/python/requirements/py3.9-requirements.txt @@ -1,10 +1,10 @@ # -# This file is autogenerated by pip-compile with python 3.9 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: # # pip-compile --output-file=sdk/python/requirements/py3.9-requirements.txt # -anyio==3.7.0 +anyio==4.0.0 # via # httpcore # starlette @@ -15,16 +15,17 @@ attrs==23.1.0 # via # bowler # jsonschema + # referencing bowler==0.9.0 # via feast (setup.py) -certifi==2023.5.7 +certifi==2023.7.22 # via # httpcore # httpx # requests -charset-normalizer==3.1.0 +charset-normalizer==3.2.0 # via requests -click==8.1.3 +click==8.1.7 # via # bowler # dask @@ -35,39 +36,43 @@ cloudpickle==2.2.1 # via dask colorama==0.4.6 # via feast (setup.py) -dask==2023.5.1 +dask==2023.9.1 # via feast (setup.py) -dill==0.3.6 +dill==0.3.7 # via feast (setup.py) -exceptiongroup==1.1.1 +exceptiongroup==1.1.3 # via anyio -fastapi==0.95.2 +fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.1 +fastavro==1.8.2 # via # feast (setup.py) # pandavro fissix==21.11.13 # via bowler -fsspec==2023.5.0 +fsspec==2023.9.0 # via dask -greenlet==2.0.2 - # via sqlalchemy -grpcio==1.54.2 +grpcio==1.57.0 # via # feast (setup.py) + # grpcio-health-checking # grpcio-reflection -grpcio-reflection==1.54.2 + # grpcio-tools +grpcio-health-checking==1.57.0 + # via feast (setup.py) +grpcio-reflection==1.57.0 # via feast (setup.py) -gunicorn==20.1.0 +grpcio-tools==1.57.0 + # via feast (setup.py) +gunicorn==21.2.0 # via feast (setup.py) h11==0.14.0 # via # httpcore # uvicorn -httpcore==0.17.2 +httpcore==0.17.3 # via httpx -httptools==0.5.0 +httptools==0.6.0 # via uvicorn httpx==0.24.1 # via feast (setup.py) @@ -76,32 +81,38 @@ idna==3.4 # anyio # httpx # requests -importlib-metadata==6.6.0 +importlib-metadata==6.8.0 # via dask jinja2==3.1.2 # via feast (setup.py) -jsonschema==4.17.3 +jsonschema==4.19.0 # via feast (setup.py) +jsonschema-specifications==2023.7.1 + # via jsonschema locket==1.0.0 # via partd markupsafe==2.1.3 # via jinja2 -mmh3==4.0.0 +mmh3==4.0.1 # via feast (setup.py) moreorless==0.4.0 # via bowler -mypy==1.3.0 +mypy==1.5.1 # via sqlalchemy mypy-extensions==1.0.0 # via mypy -numpy==1.24.3 +mypy-protobuf==3.1.0 + # via feast (setup.py) +numpy==1.25.2 # via # feast (setup.py) # pandas # pandavro # pyarrow packaging==23.1 - # via dask + # via + # dask + # gunicorn pandas==1.5.3 # via # feast (setup.py) @@ -110,36 +121,45 @@ pandavro==1.5.2 # via feast (setup.py) partd==1.4.0 # via dask -proto-plus==1.22.2 +proto-plus==1.22.3 # via feast (setup.py) -protobuf==4.23.2 +protobuf==4.23.3 # via # feast (setup.py) + # grpcio-health-checking # grpcio-reflection + # grpcio-tools + # mypy-protobuf # proto-plus pyarrow==11.0.0 # via feast (setup.py) -pydantic==1.10.8 +pydantic==1.10.12 # via # fastapi # feast (setup.py) -pygments==2.15.1 +pygments==2.16.1 # via feast (setup.py) -pyrsistent==0.19.3 - # via jsonschema python-dateutil==2.8.2 # via pandas python-dotenv==1.0.0 # via uvicorn -pytz==2023.3 +pytz==2023.3.post1 # via pandas pyyaml==6.0.1 # via # dask # feast (setup.py) # uvicorn +referencing==0.30.2 + # via + # jsonschema + # jsonschema-specifications requests==2.31.0 # via feast (setup.py) +rpds-py==0.10.2 + # via + # jsonschema + # referencing six==1.16.0 # via # pandavro @@ -149,15 +169,15 @@ sniffio==1.3.0 # anyio # httpcore # httpx -sqlalchemy[mypy]==1.4.48 +sqlalchemy[mypy]==1.4.49 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a34 +sqlalchemy2-stubs==0.0.2a35 # via sqlalchemy starlette==0.27.0 # via fastapi tabulate==0.9.0 # via feast (setup.py) -tenacity==8.2.2 +tenacity==8.2.3 # via feast (setup.py) toml==0.10.2 # via feast (setup.py) @@ -167,27 +187,34 @@ toolz==0.12.0 # via # dask # partd -tqdm==4.65.0 +tqdm==4.66.1 # via feast (setup.py) typeguard==2.13.3 # via feast (setup.py) -typing-extensions==4.6.3 +types-protobuf==4.24.0.1 + # via mypy-protobuf +typing-extensions==4.7.1 # via + # fastapi # mypy # pydantic # sqlalchemy2-stubs # starlette -urllib3==2.0.2 + # uvicorn +urllib3==2.0.4 # via requests -uvicorn[standard]==0.22.0 +uvicorn[standard]==0.23.2 # via feast (setup.py) uvloop==0.17.0 # via uvicorn volatile==2.1.0 # via bowler -watchfiles==0.19.0 +watchfiles==0.20.0 # via uvicorn websockets==11.0.3 # via uvicorn -zipp==3.15.0 +zipp==3.16.2 # via importlib-metadata + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/setup.py b/setup.py index f10322ed8a3..699d394940e 100644 --- a/setup.py +++ b/setup.py @@ -46,8 +46,11 @@ "colorama>=0.3.9,<1", "dill~=0.3.0", "fastavro>=1.1.0,<2", - "grpcio>=1.47.0,<2", - "grpcio-reflection>=1.47.0,<2", + "grpcio>=1.56.2,<2", + "grpcio-tools>=1.56.2,<2", + "grpcio-reflection>=1.56.2,<2", + "grpcio-health-checking>=1.56.2,<2", + "mypy-protobuf==3.1", "Jinja2>=2,<4", "jsonschema", "mmh3", @@ -69,7 +72,7 @@ "toml>=0.10.0,<1", "tqdm>=4,<5", "typeguard==2.13.3", - "fastapi>=0.68.0,<1", + "fastapi>=0.68.0,<0.100", "uvicorn[standard]>=0.14.0,<1", "gunicorn", "dask>=2021.1.0", @@ -142,17 +145,16 @@ CI_REQUIRED = ( [ "build", + "virtualenv==20.23.0", "cryptography>=35.0,<42", - "flake8", + "flake8>=6.0.0,<6.1.0", "black>=22.6.0,<23", "isort>=5,<6", - "grpcio-tools>=1.47.0", - "grpcio-testing>=1.47.0", + "grpcio-testing>=1.56.2,<2", "minio==7.1.0", "mock==2.0.0", "moto", "mypy>=0.981,<0.990", - "mypy-protobuf==3.1", "avro==1.10.0", "gcsfs>=0.4.0,<=2022.01.0", "urllib3>=1.25.4,<2", @@ -170,7 +172,7 @@ "testcontainers>=3.5,<4", "adlfs==0.5.9", "firebase-admin>=5.2.0,<6", - "pre-commit", + "pre-commit<3.3.2", "assertpy==1.1", "pip-tools", "pybindgen", @@ -182,6 +184,7 @@ "types-requests", "types-setuptools", "types-tabulate", + "virtualenv<20.24.2" ] + GCP_REQUIRED + REDIS_REQUIRED @@ -380,8 +383,8 @@ def run(self): use_scm_version=use_scm_version, setup_requires=[ "setuptools_scm", - "grpcio>=1.47.0", - "grpcio-tools>=1.47.0", + "grpcio>=1.56.2,<2", + "grpcio-tools>=1.56.2,<2", "mypy-protobuf==3.1", "pybindgen==0.22.0", ], From a6446d711ae7ea8440125ed60449fe9f45b9b957 Mon Sep 17 00:00:00 2001 From: Harry Date: Thu, 7 Sep 2023 11:51:00 +0700 Subject: [PATCH 041/113] fix: Add NUMERIC to bq_to_feast type map (#3719) Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- sdk/python/feast/type_map.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/python/feast/type_map.py b/sdk/python/feast/type_map.py index d246fb40545..3f490690669 100644 --- a/sdk/python/feast/type_map.py +++ b/sdk/python/feast/type_map.py @@ -528,6 +528,7 @@ def bq_to_feast_value_type(bq_type_as_str: str) -> ValueType: "DATETIME": ValueType.UNIX_TIMESTAMP, "TIMESTAMP": ValueType.UNIX_TIMESTAMP, "INTEGER": ValueType.INT64, + "NUMERIC": ValueType.INT64, "INT64": ValueType.INT64, "STRING": ValueType.STRING, "FLOAT": ValueType.DOUBLE, From 49512894ac431028aada44a314ae0949c4d1a0c4 Mon Sep 17 00:00:00 2001 From: Breno Costa <35263725+breno-costa@users.noreply.github.com> Date: Thu, 7 Sep 2023 07:31:28 +0200 Subject: [PATCH 042/113] chore: Widen redis requirement to make it easier to install alongside other requirements (#3755) * chore: wide redis dependency to make it easier to install alongside other requirements Signed-off-by: Breno Costa * update requirements Signed-off-by: Danny C --------- Signed-off-by: Breno Costa Signed-off-by: Danny C Co-authored-by: Danny C Signed-off-by: Attila Toth --- sdk/python/requirements/py3.10-ci-requirements.txt | 9 ++------- sdk/python/requirements/py3.8-ci-requirements.txt | 9 ++------- sdk/python/requirements/py3.9-ci-requirements.txt | 11 +++-------- setup.py | 2 +- 4 files changed, 8 insertions(+), 23 deletions(-) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index cb72fdaa350..a59553b4ac8 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -180,8 +180,6 @@ decorator==5.1.1 # ipython defusedxml==0.7.1 # via nbconvert -deprecated==1.2.14 - # via redis deprecation==2.1.0 # via testcontainers dill==0.3.7 @@ -577,7 +575,6 @@ packaging==23.1 # marshmallow # nbconvert # pytest - # redis # snowflake-connector-python # sphinx pandas==1.5.3 @@ -784,7 +781,7 @@ pyzmq==25.1.1 # ipykernel # jupyter-client # jupyter-server -redis==4.2.2 +redis==4.6.0 # via feast (setup.py) referencing==0.30.2 # via @@ -1065,9 +1062,7 @@ wheel==0.41.2 widgetsnbextension==4.0.8 # via ipywidgets wrapt==1.15.0 - # via - # deprecated - # testcontainers + # via testcontainers xmltodict==0.13.0 # via moto yarl==1.9.2 diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index 9dfefc21081..b24172e890f 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -184,8 +184,6 @@ decorator==5.1.1 # ipython defusedxml==0.7.1 # via nbconvert -deprecated==1.2.14 - # via redis deprecation==2.1.0 # via testcontainers dill==0.3.7 @@ -592,7 +590,6 @@ packaging==23.1 # marshmallow # nbconvert # pytest - # redis # snowflake-connector-python # sphinx pandas==1.5.3 @@ -802,7 +799,7 @@ pyzmq==25.1.1 # ipykernel # jupyter-client # jupyter-server -redis==4.2.2 +redis==4.6.0 # via feast (setup.py) referencing==0.30.2 # via @@ -1082,9 +1079,7 @@ wheel==0.41.2 widgetsnbextension==4.0.8 # via ipywidgets wrapt==1.15.0 - # via - # deprecated - # testcontainers + # via testcontainers xmltodict==0.13.0 # via moto yarl==1.9.2 diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index 3992303d00e..ad19f9e8bde 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -180,8 +180,6 @@ decorator==5.1.1 # ipython defusedxml==0.7.1 # via nbconvert -deprecated==1.2.14 - # via redis deprecation==2.1.0 # via testcontainers dill==0.3.7 @@ -527,7 +525,7 @@ mypy-extensions==1.0.0 # via # black # mypy -mypy-protobuf==3.1 +mypy-protobuf==3.1.0 # via feast (setup.py) mysqlclient==2.2.0 # via feast (setup.py) @@ -584,7 +582,6 @@ packaging==23.1 # marshmallow # nbconvert # pytest - # redis # snowflake-connector-python # sphinx pandas==1.5.3 @@ -791,7 +788,7 @@ pyzmq==25.1.1 # ipykernel # jupyter-client # jupyter-server -redis==4.2.2 +redis==4.6.0 # via feast (setup.py) referencing==0.30.2 # via @@ -1077,9 +1074,7 @@ wheel==0.41.2 widgetsnbextension==4.0.8 # via ipywidgets wrapt==1.15.0 - # via - # deprecated - # testcontainers + # via testcontainers xmltodict==0.13.0 # via moto yarl==1.9.2 diff --git a/setup.py b/setup.py index 699d394940e..573ab54d512 100644 --- a/setup.py +++ b/setup.py @@ -92,7 +92,7 @@ ] REDIS_REQUIRED = [ - "redis==4.2.2", + "redis>=4.2.2,<5", "hiredis>=2.0.0,<3", ] From 46f54b51a10193c53366e30847f073f6edafc4f2 Mon Sep 17 00:00:00 2001 From: Malcolm Keyes <78397791+malcolmk181@users.noreply.github.com> Date: Thu, 7 Sep 2023 01:51:00 -0400 Subject: [PATCH 043/113] fix: Saved datasets no longer break CLI registry-dump command (#3717) fix: Access saved dataset proto correctly in list_saved_datasets Signed-off-by: Malcolm Keyes Signed-off-by: Attila Toth --- sdk/python/feast/infra/registry/proto_registry_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/feast/infra/registry/proto_registry_utils.py b/sdk/python/feast/infra/registry/proto_registry_utils.py index 2a275703dbb..c7eeea0f822 100644 --- a/sdk/python/feast/infra/registry/proto_registry_utils.py +++ b/sdk/python/feast/infra/registry/proto_registry_utils.py @@ -214,7 +214,7 @@ def list_saved_datasets( ) -> List[SavedDataset]: saved_datasets = [] for saved_dataset in registry_proto.saved_datasets: - if saved_dataset.project == project: + if saved_dataset.spec.project == project: saved_datasets.append(SavedDataset.from_proto(saved_dataset)) return saved_datasets From ae67885480864e52e4f4d52a18e49239af947969 Mon Sep 17 00:00:00 2001 From: Dani Date: Thu, 7 Sep 2023 08:18:12 +0200 Subject: [PATCH 044/113] feat: Enhance customization of Trino connections when using Trino-based Offline Stores (#3699) * feat: Enhance customization of Trino connections when using Trino-based Offline Stores Signed-off-by: boliri * docs: Add new connection parameters to Trino Offline Store's reference Signed-off-by: boliri --------- Signed-off-by: boliri Signed-off-by: Attila Toth --- docs/reference/offline-stores/trino.md | 41 +++++ .../trino_offline_store/tests/data_source.py | 5 + .../contrib/trino_offline_store/trino.py | 164 ++++++++++++++---- .../trino_offline_store/trino_queries.py | 49 +++--- .../trino_offline_store/trino_source.py | 10 ++ 5 files changed, 209 insertions(+), 60 deletions(-) diff --git a/docs/reference/offline-stores/trino.md b/docs/reference/offline-stores/trino.md index 446db620e32..fd437a7aa67 100644 --- a/docs/reference/offline-stores/trino.md +++ b/docs/reference/offline-stores/trino.md @@ -27,6 +27,47 @@ offline_store: catalog: memory connector: type: memory + user: trino + source: feast-trino-offline-store + http-scheme: https + ssl-verify: false + x-trino-extra-credential-header: foo=bar, baz=qux + + # enables authentication in Trino connections, pick the one you need + # if you don't need authentication, you can safely remove the whole auth block + auth: + # Basic Auth + type: basic + config: + username: foo + password: $FOO + + # Certificate + type: certificate + config: + cert-file: /path/to/cert/file + key-file: /path/to/key/file + + # JWT + type: jwt + config: + token: $JWT_TOKEN + + # OAuth2 (no config required) + type: oauth2 + + # Kerberos + type: kerberos + config: + config-file: /path/to/kerberos/config/file + service-name: foo + mutual-authentication: true + force-preemptive: true + hostname-override: custom-hostname + sanitize-mutual-error-response: true + principal: principal-name + delegate: true + ca_bundle: /path/to/ca/bundle/file online_store: path: data/online_store.db ``` diff --git a/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/tests/data_source.py b/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/tests/data_source.py index 67efa6a27f8..a5aa53df7ab 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/tests/data_source.py +++ b/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/tests/data_source.py @@ -67,6 +67,11 @@ def __init__( catalog="memory", host="localhost", port=self.exposed_port, + source="trino-python-client", + http_scheme="http", + verify=False, + extra_credential=None, + auth=None, ) def teardown(self): diff --git a/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino.py b/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino.py index e0f73404ebe..f662cda9130 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino.py +++ b/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino.py @@ -1,12 +1,18 @@ import uuid from datetime import date, datetime -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, Dict, List, Literal, Optional, Tuple, Union import numpy as np import pandas as pd import pyarrow -from pydantic import StrictStr -from trino.auth import Authentication +from pydantic import Field, FilePath, SecretStr, StrictBool, StrictStr, root_validator +from trino.auth import ( + BasicAuthentication, + CertificateAuthentication, + JWTAuthentication, + KerberosAuthentication, + OAuth2Authentication, +) from feast.data_source import DataSource from feast.errors import InvalidEntityType @@ -32,6 +38,87 @@ from feast.usage import log_exceptions_and_usage +class BasicAuthModel(FeastConfigBaseModel): + username: StrictStr + password: SecretStr + + +class KerberosAuthModel(FeastConfigBaseModel): + config: Optional[FilePath] = Field(default=None, alias="config-file") + service_name: Optional[StrictStr] = Field(default=None, alias="service-name") + mutual_authentication: StrictBool = Field( + default=False, alias="mutual-authentication" + ) + force_preemptive: StrictBool = Field(default=False, alias="force-preemptive") + hostname_override: Optional[StrictStr] = Field( + default=None, alias="hostname-override" + ) + sanitize_mutual_error_response: StrictBool = Field( + default=True, alias="sanitize-mutual-error-response" + ) + principal: Optional[StrictStr] + delegate: StrictBool = False + ca_bundle: Optional[FilePath] = Field(default=None, alias="ca-bundle-file") + + +class JWTAuthModel(FeastConfigBaseModel): + token: SecretStr + + +class CertificateAuthModel(FeastConfigBaseModel): + cert: FilePath = Field(default=None, alias="cert-file") + key: FilePath = Field(default=None, alias="key-file") + + +CLASSES_BY_AUTH_TYPE = { + "kerberos": { + "auth_model": KerberosAuthModel, + "trino_auth": KerberosAuthentication, + }, + "basic": { + "auth_model": BasicAuthModel, + "trino_auth": BasicAuthentication, + }, + "jwt": { + "auth_model": JWTAuthModel, + "trino_auth": JWTAuthentication, + }, + "oauth2": { + "auth_model": None, + "trino_auth": OAuth2Authentication, + }, + "certificate": { + "auth_model": CertificateAuthModel, + "trino_auth": CertificateAuthentication, + }, +} + + +class AuthConfig(FeastConfigBaseModel): + type: Literal["kerberos", "basic", "jwt", "oauth2", "certificate"] + config: Optional[Dict[StrictStr, Any]] + + @root_validator + def config_only_nullable_for_oauth2(cls, values): + auth_type = values["type"] + auth_config = values["config"] + if auth_type != "oauth2" and auth_config is None: + raise ValueError(f"config cannot be null for auth type '{auth_type}'") + + return values + + def to_trino_auth(self): + auth_type = self.type + trino_auth_cls = CLASSES_BY_AUTH_TYPE[auth_type]["trino_auth"] + + if auth_type == "oauth2": + return trino_auth_cls() + + model_cls = CLASSES_BY_AUTH_TYPE[auth_type]["auth_model"] + model = model_cls(**self.config) + return trino_auth_cls(**model.dict()) + + class TrinoOfflineStoreConfig(FeastConfigBaseModel): """Online store config for Trino""" @@ -47,6 +134,23 @@ class TrinoOfflineStoreConfig(FeastConfigBaseModel): catalog: StrictStr """ Catalog of the Trino cluster """ + user: StrictStr + """ User of the Trino cluster """ + + source: Optional[StrictStr] = "trino-python-client" + """ ID of the feast's Trino Python client, useful for debugging """ + + http_scheme: Literal["http", "https"] = Field(default="http", alias="http-scheme") + """ HTTP scheme that should be used while establishing a connection to the Trino cluster """ + + verify: StrictBool = Field(default=True, alias="ssl-verify") + """ Whether the SSL certificate emited by the Trino cluster should be verified or not """ + + extra_credential: Optional[StrictStr] = Field( + default=None, alias="x-trino-extra-credential-header" + ) + """ Specifies the HTTP header X-Trino-Extra-Credential, e.g. user1=pwd1, user2=pwd2 """ + connector: Dict[str, str] """ Trino connector to use as well as potential extra parameters. @@ -59,6 +163,16 @@ class TrinoOfflineStoreConfig(FeastConfigBaseModel): dataset: StrictStr = "feast" """ (optional) Trino Dataset name for temporary tables """ + auth: Optional[AuthConfig] + """ + (optional) Authentication mechanism to use when connecting to Trino. Supported options are: + - kerberos + - basic + - jwt + - oauth2 + - certificate + """ + class TrinoRetrievalJob(RetrievalJob): def __init__( @@ -162,9 +276,6 @@ def pull_latest_from_table_or_query( created_timestamp_column: Optional[str], start_date: datetime, end_date: datetime, - user: Optional[str] = None, - auth: Optional[Authentication] = None, - http_scheme: Optional[str] = None, ) -> TrinoRetrievalJob: assert isinstance(config.offline_store, TrinoOfflineStoreConfig) assert isinstance(data_source, TrinoSource) @@ -181,9 +292,7 @@ def pull_latest_from_table_or_query( timestamps.append(created_timestamp_column) timestamp_desc_string = " DESC, ".join(timestamps) + " DESC" field_string = ", ".join(join_key_columns + feature_name_columns + timestamps) - client = _get_trino_client( - config=config, user=user, auth=auth, http_scheme=http_scheme - ) + client = _get_trino_client(config=config) query = f""" SELECT @@ -216,17 +325,12 @@ def get_historical_features( registry: Registry, project: str, full_feature_names: bool = False, - user: Optional[str] = None, - auth: Optional[Authentication] = None, - http_scheme: Optional[str] = None, ) -> TrinoRetrievalJob: assert isinstance(config.offline_store, TrinoOfflineStoreConfig) for fv in feature_views: assert isinstance(fv.batch_source, TrinoSource) - client = _get_trino_client( - config=config, user=user, auth=auth, http_scheme=http_scheme - ) + client = _get_trino_client(config=config) table_reference = _get_table_reference_for_new_entity( catalog=config.offline_store.catalog, @@ -307,17 +411,12 @@ def pull_all_from_table_or_query( timestamp_field: str, start_date: datetime, end_date: datetime, - user: Optional[str] = None, - auth: Optional[Authentication] = None, - http_scheme: Optional[str] = None, ) -> RetrievalJob: assert isinstance(config.offline_store, TrinoOfflineStoreConfig) assert isinstance(data_source, TrinoSource) from_expression = data_source.get_table_query_string() - client = _get_trino_client( - config=config, user=user, auth=auth, http_scheme=http_scheme - ) + client = _get_trino_client(config=config) field_string = ", ".join( join_key_columns + feature_name_columns + [timestamp_field] ) @@ -378,21 +477,22 @@ def _upload_entity_df_and_get_entity_schema( # TODO: Ensure that the table expires after some time -def _get_trino_client( - config: RepoConfig, - user: Optional[str], - auth: Optional[Any], - http_scheme: Optional[str], -) -> Trino: - client = Trino( - user=user, - catalog=config.offline_store.catalog, +def _get_trino_client(config: RepoConfig) -> Trino: + auth = None + if config.offline_store.auth is not None: + auth = config.offline_store.auth.to_trino_auth() + + return Trino( host=config.offline_store.host, port=config.offline_store.port, + user=config.offline_store.user, + catalog=config.offline_store.catalog, + source=config.offline_store.source, + http_scheme=config.offline_store.http_scheme, + verify=config.offline_store.verify, + extra_credential=config.offline_store.extra_credential, auth=auth, - http_scheme=http_scheme, ) - return client def _get_entity_df_event_timestamp_range( diff --git a/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino_queries.py b/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino_queries.py index 97c61f78a60..50472407bc6 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino_queries.py +++ b/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino_queries.py @@ -1,7 +1,6 @@ from __future__ import annotations import datetime -import os import signal from dataclasses import dataclass from enum import Enum @@ -30,34 +29,27 @@ class QueryStatus(Enum): class Trino: def __init__( self, - host: Optional[str] = None, - port: Optional[int] = None, - user: Optional[str] = None, - catalog: Optional[str] = None, - auth: Optional[Any] = None, - http_scheme: Optional[str] = None, - source: Optional[str] = None, - extra_credential: Optional[str] = None, + host: str, + port: int, + user: str, + catalog: str, + source: Optional[str], + http_scheme: str, + verify: bool, + extra_credential: Optional[str], + auth: Optional[trino.Authentication], ): - self.host = host or os.getenv("TRINO_HOST") - self.port = port or os.getenv("TRINO_PORT") - self.user = user or os.getenv("TRINO_USER") - self.catalog = catalog or os.getenv("TRINO_CATALOG") - self.auth = auth or os.getenv("TRINO_AUTH") - self.http_scheme = http_scheme or os.getenv("TRINO_HTTP_SCHEME") - self.source = source or os.getenv("TRINO_SOURCE") - self.extra_credential = extra_credential or os.getenv("TRINO_EXTRA_CREDENTIAL") + self.host = host + self.port = port + self.user = user + self.catalog = catalog + self.source = source + self.http_scheme = http_scheme + self.verify = verify + self.extra_credential = extra_credential + self.auth = auth self._cursor: Optional[Cursor] = None - if self.host is None: - raise ValueError("TRINO_HOST must be set if not passed in") - if self.port is None: - raise ValueError("TRINO_PORT must be set if not passed in") - if self.user is None: - raise ValueError("TRINO_USER must be set if not passed in") - if self.catalog is None: - raise ValueError("TRINO_CATALOG must be set if not passed in") - def _get_cursor(self) -> Cursor: if self._cursor is None: headers = ( @@ -70,9 +62,10 @@ def _get_cursor(self) -> Cursor: port=self.port, user=self.user, catalog=self.catalog, - auth=self.auth, - http_scheme=self.http_scheme, source=self.source, + http_scheme=self.http_scheme, + verify=self.verify, + auth=self.auth, http_headers=headers, ).cursor() diff --git a/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino_source.py b/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino_source.py index f09b79069ca..e618e8664ee 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino_source.py +++ b/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino_source.py @@ -227,10 +227,20 @@ def source_datatype_to_feast_value_type() -> Callable[[str], ValueType]: def get_table_column_names_and_types( self, config: RepoConfig ) -> Iterable[Tuple[str, str]]: + auth = None + if config.offline_store.auth is not None: + auth = config.offline_store.auth.to_trino_auth() + client = Trino( catalog=config.offline_store.catalog, host=config.offline_store.host, port=config.offline_store.port, + user=config.offline_store.user, + source=config.offline_store.source, + http_scheme=config.offline_store.http_scheme, + verify=config.offline_store.verify, + extra_credential=config.offline_store.extra_credential, + auth=auth, ) if self.table: table_schema = client.execute_query( From 08e11b931a31ab0147e00ab18cde5d0c4426af15 Mon Sep 17 00:00:00 2001 From: feast-ci-bot Date: Thu, 7 Sep 2023 06:53:29 +0000 Subject: [PATCH 045/113] chore(release): release 0.34.0 # [0.34.0](https://github.com/feast-dev/feast/compare/v0.33.0...v0.34.0) (2023-09-07) ### Bug Fixes * Add NUMERIC to bq_to_feast type map ([#3719](https://github.com/feast-dev/feast/issues/3719)) ([6474b4b](https://github.com/feast-dev/feast/commit/6474b4b0169dc9b3df8e8daecded2b1fad5ead58)) * Fix python unit tests ([#3734](https://github.com/feast-dev/feast/issues/3734)) ([e81684d](https://github.com/feast-dev/feast/commit/e81684d4f7916c986fa8e6cf06c2918951469799)) * Handle unknown postgres source types gracefully ([#3634](https://github.com/feast-dev/feast/issues/3634)) ([d7041f4](https://github.com/feast-dev/feast/commit/d7041f4cce813d349e9016da55d65a65c1ec2355)) * Pin protobuf version to avoid seg fault on some machines ([028cc20](https://github.com/feast-dev/feast/commit/028cc20a28118bd31deca8965782d5ad25f74300)) * Remove unwanted excessive splitting of gcs path, so expected gcs parquet paths are returned from BigQueryRetrievalJob.to_remote_storage() ([#3730](https://github.com/feast-dev/feast/issues/3730)) ([f2c5988](https://github.com/feast-dev/feast/commit/f2c59885e31f3f238dbd9c13cd1ba168e3233a9d)) * Run store.plan() only when need it. ([#3708](https://github.com/feast-dev/feast/issues/3708)) ([7bc7c47](https://github.com/feast-dev/feast/commit/7bc7c47b4507310850474290131c03fb6d480834)) * Saved datasets no longer break CLI registry-dump command ([#3717](https://github.com/feast-dev/feast/issues/3717)) ([f28ccc2](https://github.com/feast-dev/feast/commit/f28ccc2b8f42bcca943d498ad583337d4cd70383)) * Update py3.8 ci requirements for cython 3.0 release ([#3735](https://github.com/feast-dev/feast/issues/3735)) ([1695c13](https://github.com/feast-dev/feast/commit/1695c13fa8f48fdc2b5e627837043c5eea0914a9)) ### Features * Enhance customization of Trino connections when using Trino-based Offline Stores ([#3699](https://github.com/feast-dev/feast/issues/3699)) ([ed7535e](https://github.com/feast-dev/feast/commit/ed7535e23d490249ca7d224fb88e53b98d496ec0)) * Implement gRPC server to ingest streaming features ([#3687](https://github.com/feast-dev/feast/issues/3687)) ([a3fcd1f](https://github.com/feast-dev/feast/commit/a3fcd1f369bdf07174b5ecf2a49ca9864cf145d4)) Signed-off-by: Attila Toth --- CHANGELOG.md | 20 +++++++++++++++++++ infra/charts/feast-feature-server/Chart.yaml | 2 +- infra/charts/feast-feature-server/README.md | 4 ++-- infra/charts/feast-feature-server/values.yaml | 2 +- infra/charts/feast/Chart.yaml | 2 +- infra/charts/feast/README.md | 6 +++--- .../feast/charts/feature-server/Chart.yaml | 4 ++-- .../feast/charts/feature-server/README.md | 4 ++-- .../feast/charts/feature-server/values.yaml | 2 +- .../charts/transformation-service/Chart.yaml | 4 ++-- .../charts/transformation-service/README.md | 4 ++-- .../charts/transformation-service/values.yaml | 2 +- infra/charts/feast/requirements.yaml | 4 ++-- java/pom.xml | 2 +- sdk/python/feast/ui/package.json | 2 +- sdk/python/feast/ui/yarn.lock | 8 ++++---- ui/package.json | 2 +- 17 files changed, 47 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 585be439bac..f6e5a430f02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +# [0.34.0](https://github.com/feast-dev/feast/compare/v0.33.0...v0.34.0) (2023-09-07) + + +### Bug Fixes + +* Add NUMERIC to bq_to_feast type map ([#3719](https://github.com/feast-dev/feast/issues/3719)) ([6474b4b](https://github.com/feast-dev/feast/commit/6474b4b0169dc9b3df8e8daecded2b1fad5ead58)) +* Fix python unit tests ([#3734](https://github.com/feast-dev/feast/issues/3734)) ([e81684d](https://github.com/feast-dev/feast/commit/e81684d4f7916c986fa8e6cf06c2918951469799)) +* Handle unknown postgres source types gracefully ([#3634](https://github.com/feast-dev/feast/issues/3634)) ([d7041f4](https://github.com/feast-dev/feast/commit/d7041f4cce813d349e9016da55d65a65c1ec2355)) +* Pin protobuf version to avoid seg fault on some machines ([028cc20](https://github.com/feast-dev/feast/commit/028cc20a28118bd31deca8965782d5ad25f74300)) +* Remove unwanted excessive splitting of gcs path, so expected gcs parquet paths are returned from BigQueryRetrievalJob.to_remote_storage() ([#3730](https://github.com/feast-dev/feast/issues/3730)) ([f2c5988](https://github.com/feast-dev/feast/commit/f2c59885e31f3f238dbd9c13cd1ba168e3233a9d)) +* Run store.plan() only when need it. ([#3708](https://github.com/feast-dev/feast/issues/3708)) ([7bc7c47](https://github.com/feast-dev/feast/commit/7bc7c47b4507310850474290131c03fb6d480834)) +* Saved datasets no longer break CLI registry-dump command ([#3717](https://github.com/feast-dev/feast/issues/3717)) ([f28ccc2](https://github.com/feast-dev/feast/commit/f28ccc2b8f42bcca943d498ad583337d4cd70383)) +* Update py3.8 ci requirements for cython 3.0 release ([#3735](https://github.com/feast-dev/feast/issues/3735)) ([1695c13](https://github.com/feast-dev/feast/commit/1695c13fa8f48fdc2b5e627837043c5eea0914a9)) + + +### Features + +* Enhance customization of Trino connections when using Trino-based Offline Stores ([#3699](https://github.com/feast-dev/feast/issues/3699)) ([ed7535e](https://github.com/feast-dev/feast/commit/ed7535e23d490249ca7d224fb88e53b98d496ec0)) +* Implement gRPC server to ingest streaming features ([#3687](https://github.com/feast-dev/feast/issues/3687)) ([a3fcd1f](https://github.com/feast-dev/feast/commit/a3fcd1f369bdf07174b5ecf2a49ca9864cf145d4)) + # [0.33.0](https://github.com/feast-dev/feast/compare/v0.32.0...v0.33.0) (2023-08-14) diff --git a/infra/charts/feast-feature-server/Chart.yaml b/infra/charts/feast-feature-server/Chart.yaml index 3ab493fc5fb..6631d377844 100644 --- a/infra/charts/feast-feature-server/Chart.yaml +++ b/infra/charts/feast-feature-server/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: feast-feature-server description: Feast Feature Server in Go or Python type: application -version: 0.33.0 +version: 0.34.0 keywords: - machine learning - big data diff --git a/infra/charts/feast-feature-server/README.md b/infra/charts/feast-feature-server/README.md index e175f78510a..ad88d082178 100644 --- a/infra/charts/feast-feature-server/README.md +++ b/infra/charts/feast-feature-server/README.md @@ -1,6 +1,6 @@ # Feast Python / Go Feature Server Helm Charts -Current chart version is `0.33.0` +Current chart version is `0.34.0` ## Installation @@ -30,7 +30,7 @@ See [here](https://github.com/feast-dev/feast/tree/master/examples/python-helm-d | fullnameOverride | string | `""` | | | image.pullPolicy | string | `"IfNotPresent"` | | | image.repository | string | `"feastdev/feature-server"` | Docker image for Feature Server repository | -| image.tag | string | `"0.33.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | +| image.tag | string | `"0.34.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | | imagePullSecrets | list | `[]` | | | livenessProbe.initialDelaySeconds | int | `30` | | | livenessProbe.periodSeconds | int | `30` | | diff --git a/infra/charts/feast-feature-server/values.yaml b/infra/charts/feast-feature-server/values.yaml index e9d09796a31..d46f1b685b3 100644 --- a/infra/charts/feast-feature-server/values.yaml +++ b/infra/charts/feast-feature-server/values.yaml @@ -9,7 +9,7 @@ image: repository: feastdev/feature-server pullPolicy: IfNotPresent # image.tag -- The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) - tag: 0.33.0 + tag: 0.34.0 imagePullSecrets: [] nameOverride: "" diff --git a/infra/charts/feast/Chart.yaml b/infra/charts/feast/Chart.yaml index b16165808f8..e0f530e05ee 100644 --- a/infra/charts/feast/Chart.yaml +++ b/infra/charts/feast/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 description: Feature store for machine learning name: feast -version: 0.33.0 +version: 0.34.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index 846e8402361..fff6d0261bd 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -8,7 +8,7 @@ This repo contains Helm charts for Feast Java components that are being installe ## Chart: Feast -Feature store for machine learning Current chart version is `0.33.0` +Feature store for machine learning Current chart version is `0.34.0` ## Installation @@ -65,8 +65,8 @@ See [here](https://github.com/feast-dev/feast/tree/master/examples/java-demo) fo | Repository | Name | Version | |------------|------|---------| | https://charts.helm.sh/stable | redis | 10.5.6 | -| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.33.0 | -| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.33.0 | +| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.34.0 | +| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.34.0 | ## Values diff --git a/infra/charts/feast/charts/feature-server/Chart.yaml b/infra/charts/feast/charts/feature-server/Chart.yaml index 931c34f7c94..bfb33b6140f 100644 --- a/infra/charts/feast/charts/feature-server/Chart.yaml +++ b/infra/charts/feast/charts/feature-server/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 description: "Feast Feature Server: Online feature serving service for Feast" name: feature-server -version: 0.33.0 -appVersion: v0.33.0 +version: 0.34.0 +appVersion: v0.34.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/charts/feature-server/README.md b/infra/charts/feast/charts/feature-server/README.md index 653b9dfb0c4..f768a46cd53 100644 --- a/infra/charts/feast/charts/feature-server/README.md +++ b/infra/charts/feast/charts/feature-server/README.md @@ -1,6 +1,6 @@ # feature-server -![Version: 0.33.0](https://img.shields.io/badge/Version-0.33.0-informational?style=flat-square) ![AppVersion: v0.33.0](https://img.shields.io/badge/AppVersion-v0.33.0-informational?style=flat-square) +![Version: 0.34.0](https://img.shields.io/badge/Version-0.34.0-informational?style=flat-square) ![AppVersion: v0.34.0](https://img.shields.io/badge/AppVersion-v0.34.0-informational?style=flat-square) Feast Feature Server: Online feature serving service for Feast @@ -17,7 +17,7 @@ Feast Feature Server: Online feature serving service for Feast | envOverrides | object | `{}` | Extra environment variables to set | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"feastdev/feature-server-java"` | Docker image for Feature Server repository | -| image.tag | string | `"0.33.0"` | Image tag | +| image.tag | string | `"0.34.0"` | Image tag | | ingress.grpc.annotations | object | `{}` | Extra annotations for the ingress | | ingress.grpc.auth.enabled | bool | `false` | Flag to enable auth | | ingress.grpc.class | string | `"nginx"` | Which ingress controller to use | diff --git a/infra/charts/feast/charts/feature-server/values.yaml b/infra/charts/feast/charts/feature-server/values.yaml index 2403e796458..24b8da1e39a 100644 --- a/infra/charts/feast/charts/feature-server/values.yaml +++ b/infra/charts/feast/charts/feature-server/values.yaml @@ -5,7 +5,7 @@ image: # image.repository -- Docker image for Feature Server repository repository: feastdev/feature-server-java # image.tag -- Image tag - tag: 0.33.0 + tag: 0.34.0 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/charts/transformation-service/Chart.yaml b/infra/charts/feast/charts/transformation-service/Chart.yaml index 7a4e0fd7d17..5d8f157a48f 100644 --- a/infra/charts/feast/charts/transformation-service/Chart.yaml +++ b/infra/charts/feast/charts/transformation-service/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 description: "Transformation service: to compute on-demand features" name: transformation-service -version: 0.33.0 -appVersion: v0.33.0 +version: 0.34.0 +appVersion: v0.34.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/charts/transformation-service/README.md b/infra/charts/feast/charts/transformation-service/README.md index 0d217edf046..cf8c7eaae87 100644 --- a/infra/charts/feast/charts/transformation-service/README.md +++ b/infra/charts/feast/charts/transformation-service/README.md @@ -1,6 +1,6 @@ # transformation-service -![Version: 0.33.0](https://img.shields.io/badge/Version-0.33.0-informational?style=flat-square) ![AppVersion: v0.33.0](https://img.shields.io/badge/AppVersion-v0.33.0-informational?style=flat-square) +![Version: 0.34.0](https://img.shields.io/badge/Version-0.34.0-informational?style=flat-square) ![AppVersion: v0.34.0](https://img.shields.io/badge/AppVersion-v0.34.0-informational?style=flat-square) Transformation service: to compute on-demand features @@ -13,7 +13,7 @@ Transformation service: to compute on-demand features | envOverrides | object | `{}` | Extra environment variables to set | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"feastdev/feature-transformation-server"` | Docker image for Transformation Server repository | -| image.tag | string | `"0.33.0"` | Image tag | +| image.tag | string | `"0.34.0"` | Image tag | | nodeSelector | object | `{}` | Node labels for pod assignment | | podLabels | object | `{}` | Labels to be added to Feast Serving pods | | replicaCount | int | `1` | Number of pods that will be created | diff --git a/infra/charts/feast/charts/transformation-service/values.yaml b/infra/charts/feast/charts/transformation-service/values.yaml index b7fdcb66590..6af9e569ea9 100644 --- a/infra/charts/feast/charts/transformation-service/values.yaml +++ b/infra/charts/feast/charts/transformation-service/values.yaml @@ -5,7 +5,7 @@ image: # image.repository -- Docker image for Transformation Server repository repository: feastdev/feature-transformation-server # image.tag -- Image tag - tag: 0.33.0 + tag: 0.34.0 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/requirements.yaml b/infra/charts/feast/requirements.yaml index 5f855ef5278..b3236b03228 100644 --- a/infra/charts/feast/requirements.yaml +++ b/infra/charts/feast/requirements.yaml @@ -1,12 +1,12 @@ dependencies: - name: feature-server alias: feature-server - version: 0.33.0 + version: 0.34.0 condition: feature-server.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: transformation-service alias: transformation-service - version: 0.33.0 + version: 0.34.0 condition: transformation-service.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: redis diff --git a/java/pom.xml b/java/pom.xml index 0aa87a6feab..245d2d7cc6e 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -35,7 +35,7 @@ - 0.33.0 + 0.34.0 https://github.com/feast-dev/feast UTF-8 diff --git a/sdk/python/feast/ui/package.json b/sdk/python/feast/ui/package.json index 83722808820..80956440abf 100644 --- a/sdk/python/feast/ui/package.json +++ b/sdk/python/feast/ui/package.json @@ -6,7 +6,7 @@ "@elastic/datemath": "^5.0.3", "@elastic/eui": "^55.0.1", "@emotion/react": "^11.9.0", - "@feast-dev/feast-ui": "0.33.0", + "@feast-dev/feast-ui": "0.34.0", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.2.0", "@testing-library/user-event": "^13.5.0", diff --git a/sdk/python/feast/ui/yarn.lock b/sdk/python/feast/ui/yarn.lock index 28bfee06d1e..6fb431576ae 100644 --- a/sdk/python/feast/ui/yarn.lock +++ b/sdk/python/feast/ui/yarn.lock @@ -1452,10 +1452,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@feast-dev/feast-ui@0.33.0": - version "0.33.0" - resolved "https://registry.yarnpkg.com/@feast-dev/feast-ui/-/feast-ui-0.33.0.tgz#4b8f8c5376103cac1ae0f25d6c9d359e4022707a" - integrity sha512-w+wa+YpFOIbxr4zTmGPuPITQhWfYIWjv7OmL7r/9yLbtQzp/6sKKChGYZwxi6pUu1ECsRc47uuSyhYllav3InQ== +"@feast-dev/feast-ui@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@feast-dev/feast-ui/-/feast-ui-0.34.0.tgz#21799c119da936814ff47e1d1d297258ecfda098" + integrity sha512-ErrnmaFPMgnmnTpBpn7T0oiC3cA+atE5yKBmoMFXBsK6aplu18aF53QBX4JJFKMKF+A2BcO37veeXm1k01SJQQ== dependencies: "@elastic/datemath" "^5.0.3" "@elastic/eui" "^55.0.1" diff --git a/ui/package.json b/ui/package.json index b81276d8257..dc16a1e7a6a 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "@feast-dev/feast-ui", - "version": "0.33.0", + "version": "0.34.0", "private": false, "files": [ "dist" From 52eec866f819b54f0f233fa4d8b5c0d97ff05361 Mon Sep 17 00:00:00 2001 From: Danny Chiao Date: Thu, 7 Sep 2023 02:09:31 -0700 Subject: [PATCH 046/113] fix: Fix warnings from deprecated paths and update default log level (#3757) Signed-off-by: Attila Toth --- sdk/python/feast/cli.py | 6 ++-- .../feast/infra/offline_stores/file_source.py | 2 +- sdk/python/feast/proto_json.py | 8 ++--- sdk/python/feast/ui_server.py | 31 ++++++++++--------- .../requirements/py3.10-ci-requirements.txt | 3 ++ .../requirements/py3.10-requirements.txt | 6 +++- .../requirements/py3.8-ci-requirements.txt | 4 ++- .../requirements/py3.8-requirements.txt | 7 +++-- .../requirements/py3.9-ci-requirements.txt | 7 ++++- .../requirements/py3.9-requirements.txt | 10 ++++-- setup.py | 2 ++ 11 files changed, 56 insertions(+), 30 deletions(-) diff --git a/sdk/python/feast/cli.py b/sdk/python/feast/cli.py index 8c2c326b595..53c346b6eb7 100644 --- a/sdk/python/feast/cli.py +++ b/sdk/python/feast/cli.py @@ -18,10 +18,10 @@ from typing import List, Optional import click -import pkg_resources import yaml from colorama import Fore, Style from dateutil import parser +from importlib_metadata import version as importlib_version from pygments import formatters, highlight, lexers from feast import utils @@ -68,7 +68,7 @@ def format_options(self, ctx: click.Context, formatter: click.HelpFormatter): ) @click.option( "--log-level", - default="info", + default="warning", help="The logging level. One of DEBUG, INFO, WARNING, ERROR, and CRITICAL (case-insensitive).", ) @click.option( @@ -122,7 +122,7 @@ def version(): """ Display Feast SDK version """ - print(f'Feast SDK Version: "{pkg_resources.get_distribution("feast")}"') + print(f'Feast SDK Version: "{importlib_version("feast")}"') @cli.command() diff --git a/sdk/python/feast/infra/offline_stores/file_source.py b/sdk/python/feast/infra/offline_stores/file_source.py index d8522fb4456..ac824b359f4 100644 --- a/sdk/python/feast/infra/offline_stores/file_source.py +++ b/sdk/python/feast/infra/offline_stores/file_source.py @@ -158,7 +158,7 @@ def get_table_column_names_and_types( # Adding support for different file format path # based on S3 filesystem if filesystem is None: - schema = ParquetDataset(path).schema + schema = ParquetDataset(path, use_legacy_dataset=False).schema if hasattr(schema, "names") and hasattr(schema, "types"): # Newer versions of pyarrow doesn't have this method, # but this field is good enough. diff --git a/sdk/python/feast/proto_json.py b/sdk/python/feast/proto_json.py index a0a4dce86bc..41d2afa55a7 100644 --- a/sdk/python/feast/proto_json.py +++ b/sdk/python/feast/proto_json.py @@ -1,13 +1,13 @@ import uuid from typing import Any, Callable, Type -import pkg_resources from google.protobuf.json_format import ( # type: ignore _WKTJSONMETHODS, ParseError, _Parser, _Printer, ) +from importlib_metadata import version as importlib_version from packaging import version from feast.protos.feast.serving.ServingService_pb2 import FeatureList @@ -118,7 +118,7 @@ def from_json_object_updated( # https://github.com/feast-dev/feast/issues/2484 Certain feast users need a higher version of protobuf but the # parameters of `from_json_object` changes in feast 3.20.1. This change gives users flexibility to use earlier versions. - current_version = pkg_resources.get_distribution("protobuf").version + current_version = importlib_version("protobuf") if version.parse(current_version) < version.parse("3.20"): _patch_proto_json_encoding(Value, to_json_object, from_json_object) else: @@ -168,7 +168,7 @@ def from_json_object( # https://github.com/feast-dev/feast/issues/2484 Certain feast users need a higher version of protobuf but the # parameters of `from_json_object` changes in feast 3.20.1. This change gives users flexibility to use earlier versions. - current_version = pkg_resources.get_distribution("protobuf").version + current_version = importlib_version("protobuf") if version.parse(current_version) < version.parse("3.20"): _patch_proto_json_encoding(RepeatedValue, to_json_object, from_json_object) else: @@ -221,7 +221,7 @@ def from_json_object_updated( # https://github.com/feast-dev/feast/issues/2484 Certain feast users need a higher version of protobuf but the # parameters of `from_json_object` changes in feast 3.20.1. This change gives users flexibility to use earlier versions. - current_version = pkg_resources.get_distribution("protobuf").version + current_version = importlib_version("protobuf") if version.parse(current_version) < version.parse("3.20"): _patch_proto_json_encoding(FeatureList, to_json_object, from_json_object) else: diff --git a/sdk/python/feast/ui_server.py b/sdk/python/feast/ui_server.py index e750f280ad7..9950eea070f 100644 --- a/sdk/python/feast/ui_server.py +++ b/sdk/python/feast/ui_server.py @@ -2,7 +2,7 @@ import threading from typing import Callable, Optional -import pkg_resources +import importlib_resources import uvicorn from fastapi import FastAPI, Response from fastapi.middleware.cors import CORSMiddleware @@ -51,20 +51,21 @@ def shutdown_event(): async_refresh() - ui_dir = pkg_resources.resource_filename(__name__, "ui/build/") - # Initialize with the projects-list.json file - with open(ui_dir + "projects-list.json", mode="w") as f: - projects_dict = { - "projects": [ - { - "name": "Project", - "description": "Test project", - "id": project_id, - "registryPath": f"{root_path}/registry", - } - ] - } - f.write(json.dumps(projects_dict)) + ui_dir_ref = importlib_resources.files(__name__) / "ui/build/" + with importlib_resources.as_file(ui_dir_ref) as ui_dir: + # Initialize with the projects-list.json file + with ui_dir.joinpath("projects-list.json").open(mode="w") as f: + projects_dict = { + "projects": [ + { + "name": "Project", + "description": "Test project", + "id": project_id, + "registryPath": f"{root_path}/registry", + } + ] + } + f.write(json.dumps(projects_dict)) @app.get("/registry") def read_registry(): diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index a59553b4ac8..3192a154729 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -366,7 +366,10 @@ imagesize==1.4.1 importlib-metadata==6.8.0 # via # dask + # feast (setup.py) # great-expectations +importlib-resources==6.0.1 + # via feast (setup.py) iniconfig==2.0.0 # via pytest ipykernel==6.25.2 diff --git a/sdk/python/requirements/py3.10-requirements.txt b/sdk/python/requirements/py3.10-requirements.txt index 4140bea9d0f..0ebc485d6d5 100644 --- a/sdk/python/requirements/py3.10-requirements.txt +++ b/sdk/python/requirements/py3.10-requirements.txt @@ -82,7 +82,11 @@ idna==3.4 # httpx # requests importlib-metadata==6.8.0 - # via dask + # via + # dask + # feast (setup.py) +importlib-resources==6.0.1 + # via feast (setup.py) jinja2==3.1.2 # via feast (setup.py) jsonschema==4.19.0 diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index b24172e890f..a5acaf55d4f 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -370,6 +370,7 @@ importlib-metadata==6.8.0 # via # build # dask + # feast (setup.py) # great-expectations # jupyter-client # jupyter-lsp @@ -379,6 +380,7 @@ importlib-metadata==6.8.0 # sphinx importlib-resources==6.0.1 # via + # feast (setup.py) # jsonschema # jsonschema-specifications # jupyterlab @@ -533,7 +535,7 @@ mypy-extensions==1.0.0 # via # black # mypy -mypy-protobuf==3.1 +mypy-protobuf==3.1.0 # via feast (setup.py) mysqlclient==2.2.0 # via feast (setup.py) diff --git a/sdk/python/requirements/py3.8-requirements.txt b/sdk/python/requirements/py3.8-requirements.txt index 636f886133d..cccff07b7dd 100644 --- a/sdk/python/requirements/py3.8-requirements.txt +++ b/sdk/python/requirements/py3.8-requirements.txt @@ -82,9 +82,12 @@ idna==3.4 # httpx # requests importlib-metadata==6.8.0 - # via dask + # via + # dask + # feast (setup.py) importlib-resources==6.0.1 # via + # feast (setup.py) # jsonschema # jsonschema-specifications jinja2==3.1.2 @@ -105,7 +108,7 @@ mypy==1.5.1 # via sqlalchemy mypy-extensions==1.0.0 # via mypy -mypy-protobuf==3.1 +mypy-protobuf==3.1.0 # via feast (setup.py) numpy==1.24.4 # via diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index ad19f9e8bde..121a768abc1 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -367,6 +367,7 @@ importlib-metadata==6.8.0 # via # build # dask + # feast (setup.py) # great-expectations # jupyter-client # jupyter-lsp @@ -374,6 +375,8 @@ importlib-metadata==6.8.0 # jupyterlab-server # nbconvert # sphinx +importlib-resources==6.0.1 + # via feast (setup.py) iniconfig==2.0.0 # via pytest ipykernel==6.25.2 @@ -1080,7 +1083,9 @@ xmltodict==0.13.0 yarl==1.9.2 # via aiohttp zipp==3.16.2 - # via importlib-metadata + # via + # importlib-metadata + # importlib-resources # The following packages are considered to be unsafe in a requirements file: # pip diff --git a/sdk/python/requirements/py3.9-requirements.txt b/sdk/python/requirements/py3.9-requirements.txt index 7d30fd3452b..a95bcd3524f 100644 --- a/sdk/python/requirements/py3.9-requirements.txt +++ b/sdk/python/requirements/py3.9-requirements.txt @@ -82,7 +82,11 @@ idna==3.4 # httpx # requests importlib-metadata==6.8.0 - # via dask + # via + # dask + # feast (setup.py) +importlib-resources==6.0.1 + # via feast (setup.py) jinja2==3.1.2 # via feast (setup.py) jsonschema==4.19.0 @@ -214,7 +218,9 @@ watchfiles==0.20.0 websockets==11.0.3 # via uvicorn zipp==3.16.2 - # via importlib-metadata + # via + # importlib-metadata + # importlib-resources # The following packages are considered to be unsafe in a requirements file: # setuptools diff --git a/setup.py b/setup.py index 573ab54d512..cd202c9c066 100644 --- a/setup.py +++ b/setup.py @@ -79,6 +79,8 @@ "bowler", # Needed for automatic repo upgrades # FastAPI does not correctly pull starlette dependency on httpx see thread(https://github.com/tiangolo/fastapi/issues/5656). "httpx>=0.23.3", + "importlib-resources>=6.0.0,<7", + "importlib_metadata>=6.8.0,<7" ] GCP_REQUIRED = [ From 66bbfd2b929031305e080104156a0ead81803893 Mon Sep 17 00:00:00 2001 From: Nikita Demashov Date: Thu, 7 Sep 2023 21:24:55 +0300 Subject: [PATCH 047/113] fix: Set keepalives_idle None by default (#3756) set keepalives_idle None by default Co-authored-by: Nikita Demashov Signed-off-by: Attila Toth --- sdk/python/feast/infra/utils/postgres/postgres_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/feast/infra/utils/postgres/postgres_config.py b/sdk/python/feast/infra/utils/postgres/postgres_config.py index 9fbaed474d5..a4ebb456ef1 100644 --- a/sdk/python/feast/infra/utils/postgres/postgres_config.py +++ b/sdk/python/feast/infra/utils/postgres/postgres_config.py @@ -25,4 +25,4 @@ class PostgreSQLConfig(FeastConfigBaseModel): sslkey_path: Optional[StrictStr] = None sslcert_path: Optional[StrictStr] = None sslrootcert_path: Optional[StrictStr] = None - keepalives_idle: int = 0 + keepalives_idle: Optional[int] = None From 787dbd8c5723ba83735581ad9fe8ab37e1e9dd33 Mon Sep 17 00:00:00 2001 From: Danny C Date: Thu, 7 Sep 2023 13:26:00 -0700 Subject: [PATCH 048/113] fix: Pin numpy version to avoid spammy deprecation messages Signed-off-by: Danny C Signed-off-by: Attila Toth --- docs/SUMMARY.md | 1 + docs/reference/online-stores/README.md | 4 +++ .../requirements/py3.10-ci-requirements.txt | 26 +++++++++---------- .../requirements/py3.10-requirements.txt | 12 ++++----- .../requirements/py3.8-requirements.txt | 10 +++---- .../requirements/py3.9-ci-requirements.txt | 26 +++++++++---------- .../requirements/py3.9-requirements.txt | 12 ++++----- setup.py | 2 +- 8 files changed, 49 insertions(+), 44 deletions(-) diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index bf46f17060a..8affea898ef 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -90,6 +90,7 @@ * [SQLite](reference/online-stores/sqlite.md) * [Snowflake](reference/online-stores/snowflake.md) * [Redis](reference/online-stores/redis.md) + * [Dragonfly](reference/online-stores/dragonfly.md) * [Datastore](reference/online-stores/datastore.md) * [DynamoDB](reference/online-stores/dynamodb.md) * [Bigtable](reference/online-stores/bigtable.md) diff --git a/docs/reference/online-stores/README.md b/docs/reference/online-stores/README.md index dc66a89d940..7ccb118d170 100644 --- a/docs/reference/online-stores/README.md +++ b/docs/reference/online-stores/README.md @@ -18,6 +18,10 @@ Please see [Online Store](../../getting-started/architecture-and-components/onli [redis.md](redis.md) {% endcontent-ref %} +{% content-ref url="dragonfly.md" %} +[dragonfly.md](dragonfly.md) +{% endcontent-ref %} + {% content-ref url="datastore.md" %} [datastore.md](datastore.md) {% endcontent-ref %} diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index 3192a154729..cf1f4e938e5 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -58,7 +58,7 @@ attrs==23.1.0 # referencing avro==1.10.0 # via feast (setup.py) -azure-core==1.29.3 +azure-core==1.29.4 # via # adlfs # azure-identity @@ -86,11 +86,11 @@ black==22.12.0 # via feast (setup.py) bleach==6.0.0 # via nbconvert -boto3==1.28.42 +boto3==1.28.43 # via # feast (setup.py) # moto -botocore==1.31.42 +botocore==1.31.43 # via # boto3 # moto @@ -172,7 +172,7 @@ dask==2023.9.1 # via feast (setup.py) db-dtypes==1.1.1 # via google-cloud-bigquery -debugpy==1.6.7.post1 +debugpy==1.7.0 # via ipykernel decorator==5.1.1 # via @@ -208,7 +208,7 @@ executing==1.2.0 # via stack-data fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.2 +fastavro==1.8.3 # via # feast (setup.py) # pandavro @@ -307,7 +307,7 @@ great-expectations==0.15.50 # via feast (setup.py) grpc-google-iam-v1==0.12.6 # via google-cloud-bigtable -grpcio==1.57.0 +grpcio==1.58.0 # via # feast (setup.py) # google-api-core @@ -319,15 +319,15 @@ grpcio==1.57.0 # grpcio-status # grpcio-testing # grpcio-tools -grpcio-health-checking==1.57.0 +grpcio-health-checking==1.58.0 # via feast (setup.py) -grpcio-reflection==1.57.0 +grpcio-reflection==1.58.0 # via feast (setup.py) -grpcio-status==1.57.0 +grpcio-status==1.58.0 # via google-api-core -grpcio-testing==1.57.0 +grpcio-testing==1.58.0 # via feast (setup.py) -grpcio-tools==1.57.0 +grpcio-tools==1.58.0 # via feast (setup.py) gunicorn==21.2.0 # via feast (setup.py) @@ -545,7 +545,7 @@ notebook-shim==0.2.3 # via # jupyterlab # notebook -numpy==1.25.2 +numpy==1.24.4 # via # altair # db-dtypes @@ -723,7 +723,7 @@ pyproject-hooks==1.0.0 # via build pyspark==3.4.1 # via feast (setup.py) -pytest==7.4.1 +pytest==7.4.2 # via # feast (setup.py) # pytest-benchmark diff --git a/sdk/python/requirements/py3.10-requirements.txt b/sdk/python/requirements/py3.10-requirements.txt index 0ebc485d6d5..9ee910bf009 100644 --- a/sdk/python/requirements/py3.10-requirements.txt +++ b/sdk/python/requirements/py3.10-requirements.txt @@ -44,7 +44,7 @@ exceptiongroup==1.1.3 # via anyio fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.2 +fastavro==1.8.3 # via # feast (setup.py) # pandavro @@ -52,17 +52,17 @@ fissix==21.11.13 # via bowler fsspec==2023.9.0 # via dask -grpcio==1.57.0 +grpcio==1.58.0 # via # feast (setup.py) # grpcio-health-checking # grpcio-reflection # grpcio-tools -grpcio-health-checking==1.57.0 +grpcio-health-checking==1.58.0 # via feast (setup.py) -grpcio-reflection==1.57.0 +grpcio-reflection==1.58.0 # via feast (setup.py) -grpcio-tools==1.57.0 +grpcio-tools==1.58.0 # via feast (setup.py) gunicorn==21.2.0 # via feast (setup.py) @@ -107,7 +107,7 @@ mypy-extensions==1.0.0 # via mypy mypy-protobuf==3.1 # via feast (setup.py) -numpy==1.25.2 +numpy==1.24.4 # via # feast (setup.py) # pandas diff --git a/sdk/python/requirements/py3.8-requirements.txt b/sdk/python/requirements/py3.8-requirements.txt index cccff07b7dd..4011ce804f7 100644 --- a/sdk/python/requirements/py3.8-requirements.txt +++ b/sdk/python/requirements/py3.8-requirements.txt @@ -44,7 +44,7 @@ exceptiongroup==1.1.3 # via anyio fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.2 +fastavro==1.8.3 # via # feast (setup.py) # pandavro @@ -52,17 +52,17 @@ fissix==21.11.13 # via bowler fsspec==2023.9.0 # via dask -grpcio==1.57.0 +grpcio==1.58.0 # via # feast (setup.py) # grpcio-health-checking # grpcio-reflection # grpcio-tools -grpcio-health-checking==1.57.0 +grpcio-health-checking==1.58.0 # via feast (setup.py) -grpcio-reflection==1.57.0 +grpcio-reflection==1.58.0 # via feast (setup.py) -grpcio-tools==1.57.0 +grpcio-tools==1.58.0 # via feast (setup.py) gunicorn==21.2.0 # via feast (setup.py) diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index 121a768abc1..3a453153e5b 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -58,7 +58,7 @@ attrs==23.1.0 # referencing avro==1.10.0 # via feast (setup.py) -azure-core==1.29.3 +azure-core==1.29.4 # via # adlfs # azure-identity @@ -86,11 +86,11 @@ black==22.12.0 # via feast (setup.py) bleach==6.0.0 # via nbconvert -boto3==1.28.42 +boto3==1.28.43 # via # feast (setup.py) # moto -botocore==1.31.42 +botocore==1.31.43 # via # boto3 # moto @@ -172,7 +172,7 @@ dask==2023.9.1 # via feast (setup.py) db-dtypes==1.1.1 # via google-cloud-bigquery -debugpy==1.6.7.post1 +debugpy==1.7.0 # via ipykernel decorator==5.1.1 # via @@ -208,7 +208,7 @@ executing==1.2.0 # via stack-data fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.2 +fastavro==1.8.3 # via # feast (setup.py) # pandavro @@ -307,7 +307,7 @@ great-expectations==0.15.50 # via feast (setup.py) grpc-google-iam-v1==0.12.6 # via google-cloud-bigtable -grpcio==1.57.0 +grpcio==1.58.0 # via # feast (setup.py) # google-api-core @@ -319,15 +319,15 @@ grpcio==1.57.0 # grpcio-status # grpcio-testing # grpcio-tools -grpcio-health-checking==1.57.0 +grpcio-health-checking==1.58.0 # via feast (setup.py) -grpcio-reflection==1.57.0 +grpcio-reflection==1.58.0 # via feast (setup.py) -grpcio-status==1.57.0 +grpcio-status==1.58.0 # via google-api-core -grpcio-testing==1.57.0 +grpcio-testing==1.58.0 # via feast (setup.py) -grpcio-tools==1.57.0 +grpcio-tools==1.58.0 # via feast (setup.py) gunicorn==21.2.0 # via feast (setup.py) @@ -552,7 +552,7 @@ notebook-shim==0.2.3 # via # jupyterlab # notebook -numpy==1.25.2 +numpy==1.24.4 # via # altair # db-dtypes @@ -730,7 +730,7 @@ pyproject-hooks==1.0.0 # via build pyspark==3.4.1 # via feast (setup.py) -pytest==7.4.1 +pytest==7.4.2 # via # feast (setup.py) # pytest-benchmark diff --git a/sdk/python/requirements/py3.9-requirements.txt b/sdk/python/requirements/py3.9-requirements.txt index a95bcd3524f..432ac4cbe62 100644 --- a/sdk/python/requirements/py3.9-requirements.txt +++ b/sdk/python/requirements/py3.9-requirements.txt @@ -44,7 +44,7 @@ exceptiongroup==1.1.3 # via anyio fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.2 +fastavro==1.8.3 # via # feast (setup.py) # pandavro @@ -52,17 +52,17 @@ fissix==21.11.13 # via bowler fsspec==2023.9.0 # via dask -grpcio==1.57.0 +grpcio==1.58.0 # via # feast (setup.py) # grpcio-health-checking # grpcio-reflection # grpcio-tools -grpcio-health-checking==1.57.0 +grpcio-health-checking==1.58.0 # via feast (setup.py) -grpcio-reflection==1.57.0 +grpcio-reflection==1.58.0 # via feast (setup.py) -grpcio-tools==1.57.0 +grpcio-tools==1.58.0 # via feast (setup.py) gunicorn==21.2.0 # via feast (setup.py) @@ -107,7 +107,7 @@ mypy-extensions==1.0.0 # via mypy mypy-protobuf==3.1.0 # via feast (setup.py) -numpy==1.25.2 +numpy==1.24.4 # via # feast (setup.py) # pandas diff --git a/setup.py b/setup.py index cd202c9c066..f7b1ff04175 100644 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ "Jinja2>=2,<4", "jsonschema", "mmh3", - "numpy>=1.22,<3", + "numpy>=1.22,<1.25", "pandas>=1.4.3,<2", # For some reason pandavro higher than 1.5.* only support pandas less than 1.3. "pandavro~=1.5.0", From 2c1f4b3a0a043458f11f36d4f05d64ac0e61313e Mon Sep 17 00:00:00 2001 From: Jiwon Park Date: Wed, 13 Sep 2023 03:29:16 +0900 Subject: [PATCH 049/113] feat: Apply cache to load proto registry for performance (#3702) * fix: Remove unused parameter Signed-off-by: Jiwon Park * feat: Apply cache to load proto registry for performance Signed-off-by: Jiwon Park * fix: Fix update key when cache missed Signed-off-by: phil-park --------- Signed-off-by: Jiwon Park Signed-off-by: phil-park Signed-off-by: Attila Toth --- .../infra/registry/proto_registry_utils.py | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/sdk/python/feast/infra/registry/proto_registry_utils.py b/sdk/python/feast/infra/registry/proto_registry_utils.py index c7eeea0f822..e93f513b691 100644 --- a/sdk/python/feast/infra/registry/proto_registry_utils.py +++ b/sdk/python/feast/infra/registry/proto_registry_utils.py @@ -1,4 +1,5 @@ import uuid +from functools import wraps from typing import List, Optional from feast import usage @@ -23,6 +24,26 @@ from feast.stream_feature_view import StreamFeatureView +def registry_proto_cache(func): + cache_key = None + cache_value = None + + @wraps(func) + def wrapper(registry_proto: RegistryProto, project: str): + nonlocal cache_key, cache_value + + key = tuple([id(registry_proto), registry_proto.version_id, project]) + + if key == cache_key: + return cache_value + else: + cache_value = func(registry_proto, project) + cache_key = key + return cache_value + + return wrapper + + def init_project_metadata(cached_registry_proto: RegistryProto, project: str): new_project_uuid = f"{uuid.uuid4()}" usage.set_current_project_uuid(new_project_uuid) @@ -137,8 +158,9 @@ def get_validation_reference( raise ValidationReferenceNotFound(name, project=project) +@registry_proto_cache def list_feature_services( - registry_proto: RegistryProto, project: str, allow_cache: bool = False + registry_proto: RegistryProto, project: str ) -> List[FeatureService]: feature_services = [] for feature_service_proto in registry_proto.feature_services: @@ -147,6 +169,7 @@ def list_feature_services( return feature_services +@registry_proto_cache def list_feature_views( registry_proto: RegistryProto, project: str ) -> List[FeatureView]: @@ -157,6 +180,7 @@ def list_feature_views( return feature_views +@registry_proto_cache def list_request_feature_views( registry_proto: RegistryProto, project: str ) -> List[RequestFeatureView]: @@ -169,6 +193,7 @@ def list_request_feature_views( return feature_views +@registry_proto_cache def list_stream_feature_views( registry_proto: RegistryProto, project: str ) -> List[StreamFeatureView]: @@ -181,6 +206,7 @@ def list_stream_feature_views( return stream_feature_views +@registry_proto_cache def list_on_demand_feature_views( registry_proto: RegistryProto, project: str ) -> List[OnDemandFeatureView]: @@ -193,6 +219,7 @@ def list_on_demand_feature_views( return on_demand_feature_views +@registry_proto_cache def list_entities(registry_proto: RegistryProto, project: str) -> List[Entity]: entities = [] for entity_proto in registry_proto.entities: @@ -201,6 +228,7 @@ def list_entities(registry_proto: RegistryProto, project: str) -> List[Entity]: return entities +@registry_proto_cache def list_data_sources(registry_proto: RegistryProto, project: str) -> List[DataSource]: data_sources = [] for data_source_proto in registry_proto.data_sources: @@ -209,6 +237,7 @@ def list_data_sources(registry_proto: RegistryProto, project: str) -> List[DataS return data_sources +@registry_proto_cache def list_saved_datasets( registry_proto: RegistryProto, project: str ) -> List[SavedDataset]: @@ -219,6 +248,7 @@ def list_saved_datasets( return saved_datasets +@registry_proto_cache def list_validation_references( registry_proto: RegistryProto, project: str ) -> List[ValidationReference]: @@ -231,6 +261,7 @@ def list_validation_references( return validation_references +@registry_proto_cache def list_project_metadata( registry_proto: RegistryProto, project: str ) -> List[ProjectMetadata]: From c1873c79158152612dec0420050ee96acbe4e1e9 Mon Sep 17 00:00:00 2001 From: snowron <35639836+snowron@users.noreply.github.com> Date: Tue, 12 Sep 2023 22:13:30 +0300 Subject: [PATCH 050/113] feat: Add materialize and materialize-incremental rest endpoints (#3761) * resolve #3760 Signed-off-by: snowron * format feature_server.py Signed-off-by: snowron --------- Signed-off-by: snowron Signed-off-by: Attila Toth --- sdk/python/feast/feature_server.py | 43 +++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/sdk/python/feast/feature_server.py b/sdk/python/feast/feature_server.py index 3abca1d6e8e..7c638dd2481 100644 --- a/sdk/python/feast/feature_server.py +++ b/sdk/python/feast/feature_server.py @@ -1,9 +1,11 @@ import json import traceback import warnings +from typing import List, Optional import gunicorn.app.base import pandas as pd +from dateutil import parser from fastapi import FastAPI, HTTPException, Request, Response, status from fastapi.logger import logger from fastapi.params import Depends @@ -11,7 +13,7 @@ from pydantic import BaseModel import feast -from feast import proto_json +from feast import proto_json, utils from feast.data_source import PushMode from feast.errors import PushSourceNotFoundException from feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesRequest @@ -31,6 +33,17 @@ class PushFeaturesRequest(BaseModel): to: str = "online" +class MaterializeRequest(BaseModel): + start_ts: str + end_ts: str + feature_views: Optional[List[str]] = None + + +class MaterializeIncrementalRequest(BaseModel): + end_ts: str + feature_views: Optional[List[str]] = None + + def get_app(store: "feast.FeatureStore"): proto_json.patch() @@ -134,6 +147,34 @@ def write_to_online_store(body=Depends(get_body)): def health(): return Response(status_code=status.HTTP_200_OK) + @app.post("/materialize") + def materialize(body=Depends(get_body)): + try: + request = MaterializeRequest(**json.loads(body)) + store.materialize( + utils.make_tzaware(parser.parse(request.start_ts)), + utils.make_tzaware(parser.parse(request.end_ts)), + request.feature_views, + ) + except Exception as e: + # Print the original exception on the server side + logger.exception(traceback.format_exc()) + # Raise HTTPException to return the error message to the client + raise HTTPException(status_code=500, detail=str(e)) + + @app.post("/materialize-incremental") + def materialize_incremental(body=Depends(get_body)): + try: + request = MaterializeIncrementalRequest(**json.loads(body)) + store.materialize_incremental( + utils.make_tzaware(parser.parse(request.end_ts)), request.feature_views + ) + except Exception as e: + # Print the original exception on the server side + logger.exception(traceback.format_exc()) + # Raise HTTPException to return the error message to the client + raise HTTPException(status_code=500, detail=str(e)) + return app From 696b08523013701418e9436a09d634a3153ccc60 Mon Sep 17 00:00:00 2001 From: Nicholas Zeolla Date: Wed, 13 Sep 2023 20:17:40 +0100 Subject: [PATCH 051/113] feat: Add support for `table_create_disposition` in bigquery job for offline store (#3762) * Add bigquery table create disposition to offline store Signed-off-by: Nick Zeolla * linting Signed-off-by: Nick Zeolla --------- Signed-off-by: Nick Zeolla Signed-off-by: Attila Toth --- sdk/python/feast/infra/offline_stores/bigquery.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sdk/python/feast/infra/offline_stores/bigquery.py b/sdk/python/feast/infra/offline_stores/bigquery.py index 5913b60f62f..86c587c7fd2 100644 --- a/sdk/python/feast/infra/offline_stores/bigquery.py +++ b/sdk/python/feast/infra/offline_stores/bigquery.py @@ -19,7 +19,7 @@ import pandas as pd import pyarrow import pyarrow.parquet -from pydantic import StrictStr, validator +from pydantic import ConstrainedStr, StrictStr, validator from pydantic.typing import Literal from tenacity import Retrying, retry_if_exception_type, stop_after_delay, wait_fixed @@ -72,6 +72,13 @@ def get_http_client_info(): return http_client_info.ClientInfo(user_agent=get_user_agent()) +class BigQueryTableCreateDisposition(ConstrainedStr): + """Custom constraint for table_create_disposition. To understand more, see: + https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobConfigurationLoad.FIELDS.create_disposition""" + + values = {"CREATE_NEVER", "CREATE_IF_NEEDED"} + + class BigQueryOfflineStoreConfig(FeastConfigBaseModel): """Offline store config for GCP BigQuery""" @@ -95,6 +102,9 @@ class BigQueryOfflineStoreConfig(FeastConfigBaseModel): gcs_staging_location: Optional[str] = None """ (optional) GCS location used for offloading BigQuery results as parquet files.""" + table_create_disposition: Optional[BigQueryTableCreateDisposition] = None + """ (optional) Specifies whether the job is allowed to create new tables. The default value is CREATE_IF_NEEDED.""" + @validator("billing_project_id") def project_id_exists(cls, v, values, **kwargs): if v and not values["project_id"]: @@ -324,6 +334,7 @@ def write_logged_features( job_config = bigquery.LoadJobConfig( source_format=bigquery.SourceFormat.PARQUET, schema=arrow_schema_to_bq_schema(source.get_schema(registry)), + create_disposition=config.offline_store.table_create_disposition, time_partitioning=bigquery.TimePartitioning( type_=bigquery.TimePartitioningType.DAY, field=source.get_log_timestamp_column(), @@ -384,6 +395,7 @@ def offline_write_batch( job_config = bigquery.LoadJobConfig( source_format=bigquery.SourceFormat.PARQUET, schema=arrow_schema_to_bq_schema(pa_schema), + create_disposition=config.offline_store.table_create_disposition, write_disposition="WRITE_APPEND", # Default but included for clarity ) From eb0fc381ce1da34875995250ab104aa476827de1 Mon Sep 17 00:00:00 2001 From: Danny Chiao Date: Thu, 21 Sep 2023 12:48:52 -0700 Subject: [PATCH 052/113] chore: Updating docs to fix some outdated assets (e.g. release process) Signed-off-by: Danny Chiao Signed-off-by: Attila Toth --- .github/auto_assign.yml | 1 - CODEOWNERS | 11 +- README.md | 4 +- community/governance.excalidraw | 913 --------------------------- community/governance.md | 33 +- community/governance.png | Bin 258405 -> 0 bytes community/maintainers.md | 37 +- docs/README.md | 2 +- docs/community.md | 39 -- docs/getting-started/faq.md | 2 +- docs/getting-started/quickstart.md | 2 - docs/project/contributing.md | 14 +- docs/project/development-guide.md | 7 - docs/project/release-process.md | 18 +- docs/reference/feast-cli-commands.md | 2 - docs/roadmap.md | 1 - examples/quickstart/quickstart.ipynb | 1 - infra/templates/README.md.jinja2 | 3 +- sdk/python/feast/cli.py | 2 - ui/CONTRIBUTING.md | 2 +- 20 files changed, 35 insertions(+), 1059 deletions(-) delete mode 100644 community/governance.excalidraw delete mode 100644 community/governance.png diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml index 18151f74547..2a6cff517c4 100644 --- a/.github/auto_assign.yml +++ b/.github/auto_assign.yml @@ -9,7 +9,6 @@ assignees: - woop - tsotnet - achals - - adchia - felixwang9817 # A number of assignees to add to the pull request diff --git a/CODEOWNERS b/CODEOWNERS index 259c13ea3f0..4eae6d35245 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -2,16 +2,16 @@ # for more info about CODEOWNERS file # Core Interfaces -/sdk/python/feast/infra/offline_stores/offline_store.py @feast-dev/maintainers @chhabrakadabra @mavysavydav @sfc-gh-madkins +/sdk/python/feast/infra/offline_stores/offline_store.py @feast-dev/maintainers @sfc-gh-madkins /sdk/python/feast/infra/online_stores/online_store.py @feast-dev/maintainers @DvirDukhan /sdk/python/feast/infra/materialization_engine/batch_materialization_engine.py @feast-dev/maintainers @whoahbot @sfc-gh-madkins # ==== Offline Stores ==== # Core utils -/sdk/python/feast/infra/offline_stores/offline_utils.py @feast-dev/maintainers @chhabrakadabra @mavysavydav @sfc-gh-madkins +/sdk/python/feast/infra/offline_stores/offline_utils.py @feast-dev/maintainers @sfc-gh-madkins # BigQuery -/sdk/python/feast/infra/offline_stores/offline_store.py @feast-dev/maintainers @chhabrakadabra @mavysavydav +/sdk/python/feast/infra/offline_stores/offline_store.py @feast-dev/maintainers # Snowflake /sdk/python/feast/infra/offline_stores/snowflake* @sfc-gh-madkins @@ -47,8 +47,3 @@ # AWS Lambda /sdk/python/feast/infra/materialization/contrib/aws_lambda/ @achals - -# ==== Web UI ==== -/ui/ @adchia -/sdk/python/feast/ui/ @adchia -/sdk/python/feast/ui_server.py @adchia diff --git a/README.md b/README.md index f2c9348b1cc..6a851d0d417 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Feast allows ML platform teams to: * **Avoid data leakage** by generating point-in-time correct feature sets so data scientists can focus on feature engineering rather than debugging error-prone dataset joining logic. This ensure that future feature values do not leak to models during training. * **Decouple ML from data infrastructure** by providing a single data access layer that abstracts feature storage from feature retrieval, ensuring models remain portable as you move from training models to serving models, from batch models to realtime models, and from one data infra system to another. -Please see our [documentation](https://docs.feast.dev/) for more information about the project, or sign up for an [email newsletter](https://feast.dev/). +Please see our [documentation](https://docs.feast.dev/) for more information about the project. ## 📐 Architecture ![](docs/assets/feast_marchitecture.png) @@ -145,7 +145,6 @@ pprint(feature_vector) The list below contains the functionality that contributors are planning to develop for Feast. * We welcome contribution to all items in the roadmap! -* Have questions about the roadmap? Go to the Slack channel to ask on #feast-development. * **Data Sources** * [x] [Snowflake source](https://docs.feast.dev/reference/data-sources/snowflake) @@ -214,7 +213,6 @@ Please refer to the official documentation at [Documentation](https://docs.feast * [Tutorials](https://docs.feast.dev/tutorials/tutorials-overview) * [Running Feast with Snowflake/GCP/AWS](https://docs.feast.dev/how-to-guides/feast-snowflake-gcp-aws) * [Change Log](https://github.com/feast-dev/feast/blob/master/CHANGELOG.md) - * [Slack (#Feast)](https://slack.feast.dev/) ## 👋 Contributing Feast is a community project and is still under active development. Please have a look at our contributing and development guides if you want to contribute to the project: diff --git a/community/governance.excalidraw b/community/governance.excalidraw deleted file mode 100644 index f4c8dad9a4f..00000000000 --- a/community/governance.excalidraw +++ /dev/null @@ -1,913 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "type": "rectangle", - "version": 620, - "versionNonce": 853777363, - "isDeleted": false, - "id": "pr0yIJcUDXb4nFgowH9_r", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 409.5, - "y": 620.5, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 194, - "height": 83, - "seed": 1695250557, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [ - { - "id": "YfmPferxgVKoP70zGfYDK", - "type": "text" - }, - { - "id": "YfmPferxgVKoP70zGfYDK", - "type": "text" - }, - { - "type": "text", - "id": "YfmPferxgVKoP70zGfYDK" - }, - { - "id": "IsihlXUGDSklv2RsxX6wO", - "type": "arrow" - }, - { - "id": "G5s2AUFJ730fyPsIbA8xP", - "type": "arrow" - }, - { - "id": "j9ZVC3ZgHTsAGe3hJQecp", - "type": "arrow" - } - ], - "updated": 1662582134601, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 623, - "versionNonce": 328400605, - "isDeleted": false, - "id": "YfmPferxgVKoP70zGfYDK", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 414.5, - "y": 649.5, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 184, - "height": 25, - "seed": 1575229907, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1662582134601, - "link": null, - "locked": false, - "fontSize": 20, - "fontFamily": 1, - "text": "CODEOWNERS", - "baseline": 18, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "pr0yIJcUDXb4nFgowH9_r", - "originalText": "CODEOWNERS" - }, - { - "type": "rectangle", - "version": 756, - "versionNonce": 1648798067, - "isDeleted": false, - "id": "XDy4VWWtJ9sd6hzPJDdFe", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 409.5, - "y": 779.5, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 194, - "height": 83, - "seed": 1925179667, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [ - { - "id": "gUz4p_oPytb5-ejbYb81N", - "type": "text" - }, - { - "id": "gUz4p_oPytb5-ejbYb81N", - "type": "text" - }, - { - "id": "gUz4p_oPytb5-ejbYb81N", - "type": "text" - }, - { - "type": "text", - "id": "gUz4p_oPytb5-ejbYb81N" - }, - { - "id": "G5s2AUFJ730fyPsIbA8xP", - "type": "arrow" - } - ], - "updated": 1662582134601, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 781, - "versionNonce": 1240013629, - "isDeleted": false, - "id": "gUz4p_oPytb5-ejbYb81N", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 414.5, - "y": 808.5, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 184, - "height": 25, - "seed": 140322205, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1662582134601, - "link": null, - "locked": false, - "fontSize": 20, - "fontFamily": 1, - "text": "Contributors", - "baseline": 18, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "XDy4VWWtJ9sd6hzPJDdFe", - "originalText": "Contributors" - }, - { - "type": "text", - "version": 463, - "versionNonce": 2109720179, - "isDeleted": false, - "id": "AYJKq2RGJrSIpbfiJOf_4", - "fillStyle": "hachure", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 526, - "y": 517.5, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 274, - "height": 75, - "seed": 1616513981, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1662582134602, - "link": null, - "locked": false, - "fontSize": 20, - "fontFamily": 1, - "text": "1. organize contributors\n2. influence roadmap\n3. own direction of an area", - "baseline": 68, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "1. organize contributors\n2. influence roadmap\n3. own direction of an area" - }, - { - "type": "rectangle", - "version": 776, - "versionNonce": 519656573, - "isDeleted": false, - "id": "z5LT5d710gSTA9DjwiL3O", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 70, - "angle": 0, - "x": 1013.7117834394903, - "y": 187.5000000000001, - "strokeColor": "#000000", - "backgroundColor": "#4c6ef5", - "width": 132, - "height": 682, - "seed": 1424710877, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [ - { - "id": "RscqyQXicYOkFsE_zvran", - "type": "text" - }, - { - "id": "J7IG4T5j15pB3b_K0Cpd9", - "type": "arrow" - }, - { - "id": "XEohLLmfFl0L9Wi2ew5AU", - "type": "arrow" - }, - { - "id": "o3Pp-94PORhEiEauRcZW_", - "type": "arrow" - }, - { - "type": "text", - "id": "RscqyQXicYOkFsE_zvran" - }, - { - "id": "j9ZVC3ZgHTsAGe3hJQecp", - "type": "arrow" - }, - { - "id": "Klq-VJGZiolZnGuaNJ8k9", - "type": "arrow" - } - ], - "updated": 1662582138112, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 896, - "versionNonce": 1733426643, - "isDeleted": false, - "id": "RscqyQXicYOkFsE_zvran", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1018.7117834394903, - "y": 476.0000000000001, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 122, - "height": 105, - "seed": 1202400115, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1662582138113, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Feast \nGitHub \nproject", - "baseline": 95, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "z5LT5d710gSTA9DjwiL3O", - "originalText": "Feast GitHub project" - }, - { - "id": "IsihlXUGDSklv2RsxX6wO", - "type": "arrow", - "x": 506.997671158975, - "y": 619, - "width": 0, - "height": 132, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#868e96", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 345290749, - "version": 680, - "versionNonce": 787007421, - "isDeleted": false, - "boundElements": null, - "updated": 1662582134602, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 0, - -132 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "pr0yIJcUDXb4nFgowH9_r", - "focus": 0.005130630504896713, - "gap": 1.5 - }, - "endBinding": { - "elementId": "TBYpmrW2OsKEqbpZfEeJg", - "focus": 0.461338833375829, - "gap": 1 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "G5s2AUFJ730fyPsIbA8xP", - "type": "arrow", - "x": 506.9985864097345, - "y": 776, - "width": 0.9914493467237548, - "height": 71, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#868e96", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 241364467, - "version": 241, - "versionNonce": 649485971, - "isDeleted": false, - "boundElements": null, - "updated": 1662582134602, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -0.9914493467237548, - -71 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "XDy4VWWtJ9sd6hzPJDdFe", - "focus": 0.011569796958606356, - "gap": 3.5 - }, - "endBinding": { - "elementId": "pr0yIJcUDXb4nFgowH9_r", - "focus": 0.011204382815075232, - "gap": 1.5 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "TBYpmrW2OsKEqbpZfEeJg", - "type": "rectangle", - "x": 409.5, - "y": 188, - "width": 361.99999999999994, - "height": 298, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#868e96", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 30, - "groupIds": [ - "mcHoJ-dlfU3T8l_C93UPa" - ], - "strokeSharpness": "sharp", - "seed": 1515491581, - "version": 231, - "versionNonce": 593345661, - "isDeleted": false, - "boundElements": [ - { - "id": "IsihlXUGDSklv2RsxX6wO", - "type": "arrow" - }, - { - "id": "Klq-VJGZiolZnGuaNJ8k9", - "type": "arrow" - } - ], - "updated": 1662582134602, - "link": null, - "locked": false - }, - { - "id": "YEEHpa4RXaR8G9YW55v25", - "type": "rectangle", - "x": 428.5, - "y": 398, - "width": 163.61445783132532, - "height": 70.00000000000001, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [ - "mcHoJ-dlfU3T8l_C93UPa" - ], - "strokeSharpness": "sharp", - "seed": 932648787, - "version": 319, - "versionNonce": 398988755, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "8iyUZwSph5yMVrXehf6vg" - }, - { - "id": "o3Pp-94PORhEiEauRcZW_", - "type": "arrow" - }, - { - "id": "IsihlXUGDSklv2RsxX6wO", - "type": "arrow" - } - ], - "updated": 1662582134602, - "link": null, - "locked": false - }, - { - "id": "8iyUZwSph5yMVrXehf6vg", - "type": "text", - "x": 433.5, - "y": 422.5, - "width": 153.61445783132532, - "height": 21, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [ - "mcHoJ-dlfU3T8l_C93UPa" - ], - "strokeSharpness": "sharp", - "seed": 1803538003, - "version": 365, - "versionNonce": 952837341, - "isDeleted": false, - "boundElements": null, - "updated": 1662582134602, - "link": null, - "locked": false, - "text": "Area maintainers", - "fontSize": 16.697223677317968, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "middle", - "baseline": 15, - "containerId": "YEEHpa4RXaR8G9YW55v25", - "originalText": "Area maintainers" - }, - { - "type": "rectangle", - "version": 355, - "versionNonce": 1753998195, - "isDeleted": false, - "id": "Wh-PpzmGy1bWJko0akD-a", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 429.8072289156627, - "y": 257.1185567010309, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 161, - "height": 68.88144329896907, - "seed": 1844448573, - "groupIds": [ - "mcHoJ-dlfU3T8l_C93UPa" - ], - "strokeSharpness": "sharp", - "boundElements": [ - { - "id": "OJCS1hAx71BD6u1jesJzR", - "type": "text" - }, - { - "type": "text", - "id": "OJCS1hAx71BD6u1jesJzR" - }, - { - "id": "o3Pp-94PORhEiEauRcZW_", - "type": "arrow" - } - ], - "updated": 1662582134602, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 409, - "versionNonce": 556564797, - "isDeleted": false, - "id": "OJCS1hAx71BD6u1jesJzR", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 434.8072289156627, - "y": 271.55927835051546, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 151, - "height": 40, - "seed": 852504851, - "groupIds": [ - "mcHoJ-dlfU3T8l_C93UPa" - ], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1662582134602, - "link": null, - "locked": false, - "fontSize": 16.413043478260864, - "fontFamily": 1, - "text": "Project \nmaintainers", - "baseline": 34, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "Wh-PpzmGy1bWJko0akD-a", - "originalText": "Project maintainers" - }, - { - "id": "o3Pp-94PORhEiEauRcZW_", - "type": "arrow", - "x": 510.1952932956257, - "y": 396.60017389144207, - "width": 0.34508644012566947, - "height": 69.20034778288408, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [ - "mcHoJ-dlfU3T8l_C93UPa" - ], - "strokeSharpness": "sharp", - "seed": 1889236627, - "version": 572, - "versionNonce": 918879507, - "isDeleted": false, - "boundElements": null, - "updated": 1662582134602, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 0.34508644012566947, - -69.20034778288408 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "YEEHpa4RXaR8G9YW55v25", - "focus": -0.0035794947090358044, - "gap": 1.3998261085579315 - }, - "endBinding": { - "elementId": "Wh-PpzmGy1bWJko0akD-a", - "focus": -0.0051056226396315905, - "gap": 1.3998261085579884 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "4CHi-UfB3oI1PAfcFm2o_", - "type": "text", - "x": 528.5, - "y": 354.5, - "width": 218, - "height": 20, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [ - "mcHoJ-dlfU3T8l_C93UPa" - ], - "strokeSharpness": "sharp", - "seed": 2054408115, - "version": 238, - "versionNonce": 1105416605, - "isDeleted": false, - "boundElements": null, - "updated": 1662582134602, - "link": null, - "locked": false, - "text": "break ties by majority vote", - "fontSize": 16, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 14, - "containerId": null, - "originalText": "break ties by majority vote" - }, - { - "id": "gHvMhIQl4S1SxPE8kzHLx", - "type": "text", - "x": 431.8072289156627, - "y": 201.5, - "width": 157, - "height": 35, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#868e96", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [ - "mcHoJ-dlfU3T8l_C93UPa" - ], - "strokeSharpness": "sharp", - "seed": 1597289651, - "version": 154, - "versionNonce": 1038738099, - "isDeleted": false, - "boundElements": null, - "updated": 1662582134602, - "link": null, - "locked": false, - "text": "Maintainers", - "fontSize": 28, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 25, - "containerId": null, - "originalText": "Maintainers" - }, - { - "type": "text", - "version": 545, - "versionNonce": 1478563325, - "isDeleted": false, - "id": "_qJ5MtLgnvmF1-EDKX6qg", - "fillStyle": "hachure", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 533, - "y": 732.5, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 106, - "height": 25, - "seed": 1870614973, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1662582134602, - "link": null, - "locked": false, - "fontSize": 20, - "fontFamily": 1, - "text": "review PRs", - "baseline": 18, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "review PRs" - }, - { - "id": "j9ZVC3ZgHTsAGe3hJQecp", - "type": "arrow", - "x": 610.590909090909, - "y": 673.6931323855418, - "width": 394.7818338530517, - "height": 1.1368683772161603e-13, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#868e96", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1115132605, - "version": 594, - "versionNonce": 1612334739, - "isDeleted": false, - "boundElements": null, - "updated": 1662582138112, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 394.7818338530517, - 1.1368683772161603e-13 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "pr0yIJcUDXb4nFgowH9_r", - "gap": 7.0909090909090455, - "focus": 0.2817622261576348 - }, - "endBinding": { - "elementId": "z5LT5d710gSTA9DjwiL3O", - "gap": 9.339040495529549, - "focus": -0.4257863119810608 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "Klq-VJGZiolZnGuaNJ8k9", - "type": "arrow", - "x": 775.7385321100917, - "y": 334, - "width": 233.2672383568049, - "height": 0, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#868e96", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 632787667, - "version": 198, - "versionNonce": 1893334067, - "isDeleted": false, - "boundElements": null, - "updated": 1662582138112, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 233.2672383568049, - 0 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "TBYpmrW2OsKEqbpZfEeJg", - "gap": 4.238532110091741, - "focus": -0.020134228187919462 - }, - "endBinding": { - "elementId": "z5LT5d710gSTA9DjwiL3O", - "gap": 5.7060129725937765, - "focus": 0.5703812316715546 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "type": "text", - "version": 651, - "versionNonce": 1375877757, - "isDeleted": false, - "id": "diazwl57WWW_7gfm7wMea", - "fillStyle": "hachure", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 678, - "y": 637.5, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 262, - "height": 25, - "seed": 2077675699, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1662582152851, - "link": null, - "locked": false, - "fontSize": 20, - "fontFamily": 1, - "text": "merge PRs if no objections", - "baseline": 18, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "merge PRs if no objections" - }, - { - "type": "text", - "version": 658, - "versionNonce": 1558756051, - "isDeleted": false, - "id": "_T1wMHFNqfA6a8Ku2OLDl", - "fillStyle": "hachure", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 840, - "y": 296.5, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 102, - "height": 25, - "seed": 1987233139, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1662582148465, - "link": null, - "locked": false, - "fontSize": 20, - "fontFamily": 1, - "text": "merge PRs", - "baseline": 18, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "merge PRs" - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - }, - "files": {} -} \ No newline at end of file diff --git a/community/governance.md b/community/governance.md index 89cf800bc88..087b3599dbf 100644 --- a/community/governance.md +++ b/community/governance.md @@ -42,11 +42,7 @@ A formal governance structure helps us to On a high level, the key moving parts of the community are: - **GitHub activity** (issues + pull requests) -- **Slack community** ([slack.feast.dev](slack.feast.dev)) - - `#feast-development` is where design discussions happen amongst contributors - - Other Slack channels exist for users to ask and answer questions. - **RFCs** ([drive folder](https://drive.google.com/drive/u/0/folders/1msUsgmDbVBaysmhBlg9lklYLLTMk4bC3)) for detailed discussions -- **Community calls** (biweekly) to discuss best practices, contributions, and announce changes - **Maintainer syncs** (monthly) for [maintainers](maintainers.md) to discuss project direction and health With this structure, users and contributors largely self-organize and contribute changes as per [lazy consensus](#lazy-consensus). If there is active opposition and unresolvable conflict, then maintainers step in to break ties or make decisions. @@ -61,10 +57,6 @@ Anyone interested in the project can join the community to: - contribute to the project design - participate in the decision-making process. -The general decision making workflow is as follows: - - - > **Note**: There may not always a corresponding CODEOWNER for the affected code, in which case the responsibility falls on other maintainers or contributors with write access to review + merge the PR # Roles And Responsibilities @@ -96,7 +88,7 @@ In addition to their actions as users, contributors may also find themselves doi * Writing, editing, translating or reviewing the documentation * Organizing events or evangelizing the project -Contributors engage with the project through the issue tracker and slack community, or by writing or editing documentation. They submit changes to the project itself via Pull Requests (PRs), which will be considered for inclusion in the project by existing maintainers (see next section). +Contributors engage with the project through the issue tracker or by writing or editing documentation. They submit changes to the project itself via Pull Requests (PRs), which will be considered for inclusion in the project by existing maintainers (see next section). Contributors should follow the following guides when creating PRs: - [Contribution Process](https://docs.feast.dev/project/contributing) @@ -116,27 +108,14 @@ Maintainers are community members who have shown that they are committed to Feas > **Note**: maintainers, like other contributors, must make changes to Feast via pull requests (with code review). This applies to all changes to documentation, code, configuration, governance, etc. -### Types of maintainers - -There are two kinds of maintainers - -1. **Project maintainers** control overall project organization and resolving disputes. They also - - Attend a regular maintainers sync - - Participate in strategic planning, approve changes to the governance model, and manage the copyrights within the project outputs. - - (optional) Attend community calls - - (optional) Planning project roadmaps and articulating vision - - (optional) Guide design decisions to reinforce key project values (e.g. simplicity) -2. **Area maintainers** own a specific technical area (which may span code modules), often specifically targeting a user journey or tech stack. They - - are generally point people in GitHub or Slack on discussions in that area (e.g. tagged in `#feast-development`) - - (optional) help drive roadmap decisions - -> **Note:** project maintainers may also be area maintainers, but this does not give their ideas increased weight over other area maintainers. - -Decisions that need tie breakers may require intervention via project maintainers majority consensus. +Maintainers control overall project organization and resolving disputes. They also +- Attend a regular maintainers sync +- Participate in strategic planning, approve changes to the governance model, and manage the copyrights within the project outputs. +- (optional) Planning project roadmaps and articulating vision +- (optional) Guide design decisions to reinforce key project values (e.g. simplicity) ### Optional maintainer responsibilities Other optional activites a maintainer (project or area maintainer) may participate in: - * Monitor email aliases and our Slack (#feast-general, #feast-development, #feast-beginners). * Perform code reviews for other maintainers and the community. The areas of specialization listed in [OWNERS.md](OWNERS.md) can be used to help with routing an issue/question to the right person. * Triage GitHub issues, applying [labels]([https://github.com/feast-dev/feast/labels](https://github.com/feast-dev/feast/labels)) to each new item. Labels are extremely useful for future issue follow ups. Adding labels is somewhat subjective, so please use your best judgment. * Triage build issues, filing issues for known flaky builds or bugs, fixing or finding someone to fix any master build breakages. diff --git a/community/governance.png b/community/governance.png deleted file mode 100644 index c2b00930e3a3d4e4676ab80817e0cb364ff84777..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 258405 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

V08LI?>v4AIPGz_w5sVZ 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�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Ð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 L8tYf+IsNf(^|&9| diff --git a/community/maintainers.md b/community/maintainers.md index cdf78b150cd..e66dbeb7629 100644 --- a/community/maintainers.md +++ b/community/maintainers.md @@ -7,36 +7,25 @@ See [Governance](governance.md) for what each maintainer type is In alphabetical order | Name | GitHub Username | Email | Organization | -| -------------- | ---------------- | --------------------------- | ------------------ | -| Abhin Chhabra | `chhabrakadabra` | chhabra.abhin@gmail.com | Shopify | +| -------------- | ---------------- |-----------------------------| ------------------ | | Achal Shah | `achals` | achals@gmail.com | Tecton | -| Danny Chiao | `adchia` | d.chiao@gmail.com | Tecton | -| David Liu | `mavysavydav` | davidyliuliu@gmail.com | Twitter | | Felix Wang | `felixwang9817` | wangfelix98@gmail.com | Tecton | | Kevin Zhang | `kevjumba` | kevin.zhang.13499@gmail.com | Tecton | -| Matt Delacour | `MattDelac` | mdelacour@hey.com | (formerly) Shopify | | Miles Adkins | `sfc-gh-madkins` | miles.adkins@snowflake.com | Snowflake | | Willem Pienaar | `woop` | will.pienaar@gmail.com | Tecton | | Zhiling Chen | `zhilingc` | chnzhlng@gmail.com | GetGround | -## Area maintainers - -Generally, with contribution questions here, default to `#feast-development` in the [slack.feast.dev](slack.feast.dev) Slack channel, but these may be folks for you to tag in messages - -| Area | Description | Name | -| -------------------- | -------------------------------------------------------------------------- | --------------------------------------------- | -| Data ingestion | ingesting batch + stream data into the online store (materialization) | Achal Shah,
Felix Wang,
Kevin Zhang | -| Developer experience | tooling, testing, documentation, tutorials | Achal Shah | -| Feature serving | optimization, caching, deployment patterns, batch retrieval, range queries | Dvir Dukhan | -| Ops | general deployment concerns, CI/CD, versioning | Keith Adler,
Danny Chiao,
Felix Wang | -| Web UI | i.e. `feast ui` output | Danny Chiao,
David Liu | - ## Emeritus Maintainers -| Name | GitHub Username | Email | Organization | -| ------------------- | --------------- | --------------------------- | ------------ | -| Oleg Avdeev | oavdeev | oleg.v.avdeev@gmail.com | Tecton | -| Oleksii Moskalenko | pyalex | moskalenko.alexey@gmail.com | Tecton | -| Jay Parthasarthy | jparthasarthy | jparthasarthy@gmail.com | Tecton | -| Pradithya Aria Pura | pradithya | pradithya.aria@gmail.com | Gojek | -| Tsotne Tabidze | tsotnet | tsotnet@gmail.com | Tecton | \ No newline at end of file +| Name | GitHub Username | Email | Organization | +|---------------------|-----------------|-----------------------------|-------------------| +| Oleg Avdeev | oavdeev | oleg.v.avdeev@gmail.com | Tecton | +| Oleksii Moskalenko | pyalex | moskalenko.alexey@gmail.com | Tecton | +| Jay Parthasarthy | jparthasarthy | jparthasarthy@gmail.com | Tecton | +| Danny Chiao | adchia | danny@tecton.ai | Tecton | +| Pradithya Aria Pura | pradithya | pradithya.aria@gmail.com | Gojek | +| Tsotne Tabidze | tsotnet | tsotnet@gmail.com | Tecton | +| Abhin Chhabra | chhabrakadabra | chhabra.abhin@gmail.com | Shopify | +| Danny Chiao | adchia | danny@tecton.ai | Tecton | +| David Liu | mavysavydav | davidyliuliu@gmail.com | Twitter | +| Matt Delacour | MattDelac | mdelacour@hey.com | Shopify | diff --git a/docs/README.md b/docs/README.md index a305c4aecde..66c7548440b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -57,7 +57,7 @@ Many companies have used Feast to power real-world ML use cases such as: ## How can I get started? {% hint style="info" %} -The best way to learn Feast is to use it. Join our [Slack channel](http://slack.feast.dev) and head over to our [Quickstart](getting-started/quickstart.md) and try it out! +The best way to learn Feast is to use it. Head over to our [Quickstart](getting-started/quickstart.md) and try it out! {% endhint %} Explore the following resources to get started with Feast: diff --git a/docs/community.md b/docs/community.md index 098b6b3f90b..21cca702bf1 100644 --- a/docs/community.md +++ b/docs/community.md @@ -4,13 +4,6 @@ * [GitHub Repository](https://github.com/feast-dev/feast/): Find the complete Feast codebase on GitHub. * [Community Governance Doc](https://github.com/feast-dev/feast/blob/master/community): See the governance model of Feast, including who the maintainers are and how decisions are made. -* [Slack](https://slack.feast.dev): Feel free to ask questions or say hello! This is the main place where maintainers and contributors brainstorm and where users ask questions or discuss best practices. - * Feast users should join `#feast-general` or `#feast-beginners` to ask questions - * Feast developers / contributors should join `#feast-development` -* [Mailing list](https://groups.google.com/d/forum/feast-dev): We have both a user and developer mailing list. - * Feast users should join [feast-discuss@googlegroups.com](mailto:feast-discuss@googlegroups.com) group by clicking [here](https://groups.google.com/g/feast-discuss). - * Feast developers / contributors should join [feast-dev@googlegroups.com](mailto:feast-dev@googlegroups.com) group by clicking [here](https://groups.google.com/d/forum/feast-dev). -* [Community Calendar](https://calendar.google.com/calendar/u/0?cid=ZTFsZHVhdGM3MDU3YTJucTBwMzNqNW5rajBAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ): Includes community calls and design meetings. * [Google Folder](https://drive.google.com/drive/u/0/folders/1jgMHOPDT2DvBlJeO9LCM79DP4lm4eOrR): This folder is used as a central repository for all Feast resources. For example: * Design proposals in the form of Request for Comments (RFC). * User surveys and meeting minutes. @@ -19,36 +12,4 @@ ## How can I get help? -* **Slack:** Need to speak to a human? Come ask a question in our Slack channel (link above). * **GitHub Issues:** Found a bug or need a feature? [Create an issue on GitHub](https://github.com/feast-dev/feast/issues/new). -* **StackOverflow:** Need to ask a question on how to use Feast? We also monitor and respond to [StackOverflow](https://stackoverflow.com/questions/tagged/feast). - -## Community Calls - -### General community call (biweekly) -We have a user and contributor community call every two weeks (US & EU friendly). - -{% hint style="info" %} -Please join the above Feast user groups in order to see calendar invites to the community calls -{% endhint %} - -#### Frequency (every 2 weeks) - -* Tuesday 10:00 am to 10:30 am PST - -#### Links - -* Zoom: [https://zoom.us/j/6325193230](https://zoom.us/j/6325193230) -* Meeting notes (incl recordings): [https://bit.ly/feast-notes](https://bit.ly/feast-notes) - -### Developers call (biweekly) -We also have a `#feast-development` community call every two weeks, where we discuss contributions + brainstorm best practices. - -#### Frequency (every 2 weeks) - -* Tuesday 8:00 am to 8:30 am PST - -#### Links - -* Meeting notes (incl recordings): [Feast Development Biweekly](https://docs.google.com/document/d/1zUbIWFWjaBEVlToOdupnmKQwgAtFYx41sPoEEEdd2io/edit#) -* Zoom: [https://zoom.us/j/93657748160?pwd=K3ZpdzhqejgrcXNhc3BlSjFMdzUxdz09](https://zoom.us/j/93657748160?pwd=K3ZpdzhqejgrcXNhc3BlSjFMdzUxdz09) diff --git a/docs/getting-started/faq.md b/docs/getting-started/faq.md index a511ddb0dc2..9b7eb834bf2 100644 --- a/docs/getting-started/faq.md +++ b/docs/getting-started/faq.md @@ -3,7 +3,7 @@ {% hint style="info" %} **Don't see your question?** -We encourage you to ask questions on [Slack](https://slack.feast.dev) or [GitHub](https://github.com/feast-dev/feast). Even better, once you get an answer, add the answer to this FAQ via a [pull request](../project/development-guide.md)! +We encourage you to ask questions on [GitHub](https://github.com/feast-dev/feast). Even better, once you get an answer, add the answer to this FAQ via a [pull request](../project/development-guide.md)! {% endhint %} ## Getting started diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md index b30bdb585c7..d10e8a174ab 100644 --- a/docs/getting-started/quickstart.md +++ b/docs/getting-started/quickstart.md @@ -555,9 +555,7 @@ show up in the upcoming concepts + architecture + tutorial pages as well. ## Next steps -* Join the [email newsletter](https://feast.dev/) to get new updates on Feast / feature stores. * Read the [Concepts](concepts/) page to understand the Feast data model. * Read the [Architecture](architecture-and-components/) page. * Check out our [Tutorials](../tutorials/tutorials-overview/) section for more examples on how to use Feast. * Follow our [Running Feast with Snowflake/GCP/AWS](../how-to-guides/feast-snowflake-gcp-aws/) guide for a more in-depth tutorial on using Feast. -* Join other Feast users and contributors in [Slack](https://slack.feast.dev) and become part of the community! diff --git a/docs/project/contributing.md b/docs/project/contributing.md index 9a3e3e1a3ea..cded378951d 100644 --- a/docs/project/contributing.md +++ b/docs/project/contributing.md @@ -2,21 +2,15 @@ ## Getting started After familiarizing yourself with the documentation, the simplest way to get started is to: -1. Join the `#feast-development` [Slack channel](https://tectonfeast.slack.com/archives/C01NTDB88QK), where contributors discuss ideas and PRs -2. Join our Google Groups in order to get access to RFC folders + get invites to community calls. See [community](../community.md) for more details. -3. Setup your developer environment by following [development guide](development-guide.md). -4. Either create a [GitHub issue](https://github.com/feast-dev/feast/issues) or make a draft PR (following [development guide](development-guide.md)) to get the ball rolling! +1. Setup your developer environment by following [development guide](development-guide.md). +2. Either create a [GitHub issue](https://github.com/feast-dev/feast/issues) or make a draft PR (following [development guide](development-guide.md)) to get the ball rolling! ## Decision making process *See [governance](../../community/governance.md) for more details here* We follow a process of [lazy consensus](http://community.apache.org/committers/lazyConsensus.html). If you believe you know what the project needs then just start development. As long as there is no active opposition and the PR has been approved by maintainers or CODEOWNERS, contributions will be merged. -We use our `#feast-development` [Slack channel](https://tectonfeast.slack.com/archives/C01NTDB88QK), [GitHub issues](https://github.com/feast-dev/feast/issues), and [GitHub pull requests](https://github.com/feast-dev/feast/pulls) to communicate development ideas. - -The general decision making workflow is as follows: - - +We use our [GitHub issues](https://github.com/feast-dev/feast/issues), and [GitHub pull requests](https://github.com/feast-dev/feast/pulls) to communicate development ideas. > **Note**: There may not always a corresponding CODEOWNER for the affected code, in which case the responsibility falls on other maintainers or contributors with write access to review + merge the PR @@ -30,7 +24,7 @@ See also [Making a pull request](development-guide.md#making-a-pull-request) for ## Resources -- [Community](../community.md) for other ways to get involved with the community (e.g. joining community calls) +- [Community](../community.md) for other ways to get involved with the community - [Development guide](development-guide.md) for tips on how to contribute - [Feast GitHub issues](https://github.com/feast-dev/feast/issues) to see what others are working on - [Feast RFCs](https://drive.google.com/drive/u/0/folders/1msUsgmDbVBaysmhBlg9lklYLLTMk4bC3) for a folder of previously written RFCs \ No newline at end of file diff --git a/docs/project/development-guide.md b/docs/project/development-guide.md index 69a1ab298a4..931d0243d2b 100644 --- a/docs/project/development-guide.md +++ b/docs/project/development-guide.md @@ -51,13 +51,6 @@ The compatibility policy for Feast can be found [here](compatibility.md), and sh ## Community See [Contribution process](./contributing.md) and [Community](../community.md) for details on how to get more involved in the community. -A quick few highlights: -- [RFCs](https://drive.google.com/drive/u/0/folders/0AAe8j7ZK3sxSUk9PVA) -- [Community Slack](https://slack.feast.dev/) -- [Feast Dev Mailing List](https://groups.google.com/g/feast-dev) -- [Community Calendar](https://calendar.google.com/calendar/u/0?cid=ZTFsZHVhdGM3MDU3YTJucTBwMzNqNW5rajBAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ) - - Includes biweekly community calls at 10AM PST - ## Making a pull request We use the convention that the assignee of a PR is the person with the next action. diff --git a/docs/project/release-process.md b/docs/project/release-process.md index 0aa7d3fb5ba..d3ff34bbc38 100644 --- a/docs/project/release-process.md +++ b/docs/project/release-process.md @@ -16,14 +16,14 @@ If you were cutting Feast 0.22.3, for example, you might do: After this step, you will have all the changes you need in the branch. -### 2. Pre-release verification +### 2. Pre-release verification (currently broken) A lot of things can go wrong. One of the most common is getting the wheels to build correctly (and not accidentally building dev wheels from improper tagging or local code changes during the release process). Another possible failure is that the Docker images might not build correctly. We verify the building the wheels and Docker images in **your fork** of Feast, not the main feast-dev/feast repo. -#### For minor releases (e.g. v0.22.0) +#### 2a. Verifying minor releases (e.g. v0.22.0) 1. Merge upstream master changes into your **fork**. Make sure you are running the workflow off of your fork! 2. Create a tag manually for the release on your fork. For example, if you are doing a release for version 0.22.0, create a tag by doing the following. - Checkout master branch and run `git tag v0.22.0`. @@ -37,17 +37,7 @@ We verify the building the wheels and Docker images in **your fork** of Feast, n 5. Run the workflow off of the tag you just created(`v0.22.0` in this case, **not** the master branch) and verify that the workflow worked (i.e ensure that all jobs are green). -#### For patch releases (e.g. v0.22.3) -You should already have checked out the existing minor release branch from step 1 (e.g. `v0.22-branch`). -1. Push the minor release branch to your fork (`git push -u origin `). -2. Add a patch release tag (e.g `v0.22.1`) by running `git tag `. - > This is important. If you don't have a tag, then the wheels you build will be **dev wheels**, which we can't - > push. The release process will automatically produce a tag for you via Semantic Release. -3. Push tags to your **origin branch** (not the upstream feast-dev/feast branch) with `git push origin `. -4. Kick off `build_wheels` workflow in your fork in the same way as is detailed in the last section, running the - workflow from this tag you just pushed up. - -### 3. Release for Python and Java SDK +### 2. Release for Python and Java SDK 1. Generate a [Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) or retrieve your saved personal access token. * The personal access token should have all of the permissions under the `repo` checkbox. 2. Access the `Actions` tab on the main `feast-dev/feast` repo and find the `release` action. @@ -81,7 +71,7 @@ so it helps to have a high level overview. See https://github.com/feast-dev/feas #### 4c: Update documentation -In the Feast Gitbook (ask [Danny Chiao](https://tectonfeast.slack.com/team/U029405HFEU) in Slack for access): +In the Feast Gitbook: 1. Create a new space within the Feast collection 2. Go to the overflow menu on the top -> Synchronize with Git 1. Specify GitHub as the provider diff --git a/docs/reference/feast-cli-commands.md b/docs/reference/feast-cli-commands.md index 38e85843d41..7bdea19e610 100644 --- a/docs/reference/feast-cli-commands.md +++ b/docs/reference/feast-cli-commands.md @@ -11,8 +11,6 @@ Usage: feast [OPTIONS] COMMAND [ARGS]... For more information, see our public docs at https://docs.feast.dev/ - For any questions, you can reach us at https://slack.feast.dev/ - Options: -c, --chdir TEXT Switch to a different feature repository directory before executing the given subcommand. diff --git a/docs/roadmap.md b/docs/roadmap.md index d5dc88005bf..a04ede7c993 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -3,7 +3,6 @@ The list below contains the functionality that contributors are planning to develop for Feast. * We welcome contribution to all items in the roadmap! -* Have questions about the roadmap? Go to the Slack channel to ask on #feast-development. * **Data Sources** * [x] [Snowflake source](https://docs.feast.dev/reference/data-sources/snowflake) diff --git a/examples/quickstart/quickstart.ipynb b/examples/quickstart/quickstart.ipynb index 6e07d3e23bc..f84457ac02d 100644 --- a/examples/quickstart/quickstart.ipynb +++ b/examples/quickstart/quickstart.ipynb @@ -1066,7 +1066,6 @@ "- Read the [Concepts](https://docs.feast.dev/getting-started/concepts/) page to understand the Feast data model and architecture.\n", "- Check out our [Tutorials](https://docs.feast.dev/tutorials/tutorials-overview) section for more examples on how to use Feast.\n", "- Follow our [Running Feast with Snowflake/GCP/AWS](https://docs.feast.dev/how-to-guides/feast-snowflake-gcp-aws) guide for a more in-depth tutorial on using Feast.\n", - "- Join other Feast users and contributors in [Slack](https://slack.feast.dev/) and become part of the community!" ] } ], diff --git a/infra/templates/README.md.jinja2 b/infra/templates/README.md.jinja2 index 47779d4eb7f..1cce08ecfac 100644 --- a/infra/templates/README.md.jinja2 +++ b/infra/templates/README.md.jinja2 @@ -25,7 +25,7 @@ Feast allows ML platform teams to: * **Avoid data leakage** by generating point-in-time correct feature sets so data scientists can focus on feature engineering rather than debugging error-prone dataset joining logic. This ensure that future feature values do not leak to models during training. * **Decouple ML from data infrastructure** by providing a single data access layer that abstracts feature storage from feature retrieval, ensuring models remain portable as you move from training models to serving models, from batch models to realtime models, and from one data infra system to another. -Please see our [documentation](https://docs.feast.dev/) for more information about the project, or sign up for an [email newsletter](https://feast.dev/). +Please see our [documentation](https://docs.feast.dev/) for more information about the project. ## 📐 Architecture ![](docs/assets/feast_marchitecture.png) @@ -149,7 +149,6 @@ Please refer to the official documentation at [Documentation](https://docs.feast * [Tutorials](https://docs.feast.dev/tutorials/tutorials-overview) * [Running Feast with Snowflake/GCP/AWS](https://docs.feast.dev/how-to-guides/feast-snowflake-gcp-aws) * [Change Log](https://github.com/feast-dev/feast/blob/master/CHANGELOG.md) - * [Slack (#Feast)](https://slack.feast.dev/) ## 👋 Contributing Feast is a community project and is still under active development. Please have a look at our contributing and development guides if you want to contribute to the project: diff --git a/sdk/python/feast/cli.py b/sdk/python/feast/cli.py index 53c346b6eb7..3153f02e518 100644 --- a/sdk/python/feast/cli.py +++ b/sdk/python/feast/cli.py @@ -86,8 +86,6 @@ def cli( Feast CLI For more information, see our public docs at https://docs.feast.dev/ - - For any questions, you can reach us at https://slack.feast.dev/ """ ctx.ensure_object(dict) ctx.obj["CHDIR"] = Path.cwd() if chdir is None else Path(chdir).absolute() diff --git a/ui/CONTRIBUTING.md b/ui/CONTRIBUTING.md index 970bd3676cd..3c13759e260 100644 --- a/ui/CONTRIBUTING.md +++ b/ui/CONTRIBUTING.md @@ -91,7 +91,7 @@ The Feast UI is published as a module to NPM and can be found here: https://www. ### Requirements To publish a new version of the module, you will need: -- to be part of the @feast-dev team in NPM. Ask `#feast-development` on http://slack.feast.dev to add you if necessary. +- to be part of the @feast-dev team in NPM. - to [login to your NPM account on the command line](https://docs.npmjs.com/cli/v8/commands/npm-adduser). ### Steps for Publishing From 22a5b41be56bfa818ec79e3456f29e2ec4dac211 Mon Sep 17 00:00:00 2001 From: James Crabtree <77012363+james-crabtree-sp@users.noreply.github.com> Date: Thu, 21 Sep 2023 14:53:10 -0500 Subject: [PATCH 053/113] feat: Add support for in_cluster config and additional labels for bytewax materialization (#3754) * SAASMLOPS-734 bytewax in-cluster config, custom labels, fix worker image deps Signed-off-by: James Crabtree * SAASMLOPS-769 make max parallelism configurable Signed-off-by: James Crabtree --------- Signed-off-by: James Crabtree Signed-off-by: Attila Toth --- .../bytewax/bytewax_materialization_engine.py | 25 +++++++++++-------- setup.py | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py index b222128bbbe..21b7a5da1fa 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py @@ -61,6 +61,12 @@ class BytewaxMaterializationEngineConfig(FeastConfigBaseModel): include_security_context_capabilities: bool = True """ (optional) Include security context capabilities in the init and job container spec """ + labels: dict = {} + """ (optional) additional labels to append to kubernetes objects """ + + max_parallelism: int = 10 + """ (optional) Maximum number of pods (default 10) allowed to run in parallel per job""" + class BytewaxMaterializationEngine(BatchMaterializationEngine): def __init__( @@ -82,7 +88,7 @@ def __init__( self.online_store = online_store # TODO: Configure k8s here - k8s_config.load_kube_config() + k8s_config.load_config() self.k8s_client = client.api_client.ApiClient() self.v1 = client.CoreV1Api(self.k8s_client) @@ -196,14 +202,13 @@ def _create_configuration_map(self, job_id, paths, feature_view, namespace): {"paths": paths, "feature_view": feature_view.name} ) + labels = {"feast-bytewax-materializer": "configmap"} configmap_manifest = { "kind": "ConfigMap", "apiVersion": "v1", "metadata": { "name": f"feast-{job_id}", - "labels": { - "feast-bytewax-materializer": "configmap", - }, + "labels": {**labels, **self.batch_engine_config.labels}, }, "data": { "feature_store.yaml": feature_store_configuration, @@ -260,27 +265,25 @@ def _create_job_definition(self, job_id, namespace, pods, env): "drop": ["ALL"], } + job_labels = {"feast-bytewax-materializer": "job"} + pod_labels = {"feast-bytewax-materializer": "pod"} job_definition = { "apiVersion": "batch/v1", "kind": "Job", "metadata": { "name": f"dataflow-{job_id}", "namespace": namespace, - "labels": { - "feast-bytewax-materializer": "job", - }, + "labels": {**job_labels, **self.batch_engine_config.labels}, }, "spec": { "ttlSecondsAfterFinished": 3600, "completions": pods, - "parallelism": pods, + "parallelism": min(pods, self.batch_engine_config.max_parallelism), "completionMode": "Indexed", "template": { "metadata": { "annotations": self.batch_engine_config.annotations, - "labels": { - "feast-bytewax-materializer": "pod", - }, + "labels": {**pod_labels, **self.batch_engine_config.labels}, }, "spec": { "restartPolicy": "Never", diff --git a/setup.py b/setup.py index f7b1ff04175..047100f03eb 100644 --- a/setup.py +++ b/setup.py @@ -98,7 +98,7 @@ "hiredis>=2.0.0,<3", ] -AWS_REQUIRED = ["boto3>=1.17.0,<2", "docker>=5.0.2"] +AWS_REQUIRED = ["boto3>=1.17.0,<2", "docker>=5.0.2", "s3fs"] BYTEWAX_REQUIRED = ["bytewax==0.15.1", "docker>=5.0.2", "kubernetes<=20.13.0"] From 1ab82c95d14bad3224781645d43a2dbe1ba1e4da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 10:26:40 -0700 Subject: [PATCH 054/113] chore: Bump org.apache.avro:avro from 1.10.2 to 1.11.3 in /java/serving (#3775) Bumps org.apache.avro:avro from 1.10.2 to 1.11.3. --- updated-dependencies: - dependency-name: org.apache.avro:avro dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- java/serving/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/serving/pom.xml b/java/serving/pom.xml index 79f942d4918..19e54e1362b 100644 --- a/java/serving/pom.xml +++ b/java/serving/pom.xml @@ -274,7 +274,7 @@ org.apache.avro avro - 1.10.2 + 1.11.3 From d346a93167b54188d3c6029dea3fc43bd86e2491 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 10:26:57 -0700 Subject: [PATCH 055/113] chore: Bump cryptography from 41.0.3 to 41.0.4 in /sdk/python/requirements (#3773) chore: Bump cryptography in /sdk/python/requirements Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.3 to 41.0.4. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.3...41.0.4) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/requirements/py3.10-ci-requirements.txt | 2 +- sdk/python/requirements/py3.8-ci-requirements.txt | 2 +- sdk/python/requirements/py3.9-ci-requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index cf1f4e938e5..46b6303a907 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -154,7 +154,7 @@ comm==0.1.4 # ipywidgets coverage[toml]==7.3.1 # via pytest-cov -cryptography==41.0.3 +cryptography==41.0.4 # via # adal # azure-identity diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index a5acaf55d4f..01190cef29a 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -158,7 +158,7 @@ comm==0.1.4 # ipywidgets coverage[toml]==7.3.1 # via pytest-cov -cryptography==41.0.3 +cryptography==41.0.4 # via # adal # azure-identity diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index 3a453153e5b..eabc2c0b8f1 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -154,7 +154,7 @@ comm==0.1.4 # ipywidgets coverage[toml]==7.3.1 # via pytest-cov -cryptography==41.0.3 +cryptography==41.0.4 # via # adal # azure-identity From 8ce3ed61f2250d8233c8aa8398930817fcc77cc6 Mon Sep 17 00:00:00 2001 From: snowron <35639836+snowron@users.noreply.github.com> Date: Thu, 12 Oct 2023 00:13:20 +0300 Subject: [PATCH 056/113] fix: UI project cannot handle fallback routes (#3766) * fix: fallback route cannot navigate to react page Signed-off-by: snowron Signed-off-by: Danny Chiao * refactor fix Signed-off-by: snowron --------- Signed-off-by: snowron Signed-off-by: Danny Chiao Signed-off-by: Attila Toth --- sdk/python/feast/ui_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/feast/ui_server.py b/sdk/python/feast/ui_server.py index 9950eea070f..8a39293f918 100644 --- a/sdk/python/feast/ui_server.py +++ b/sdk/python/feast/ui_server.py @@ -77,7 +77,7 @@ def read_registry(): # For all other paths (such as paths that would otherwise be handled by react router), pass to React @app.api_route("/p/{path_name:path}", methods=["GET"]) def catch_all(): - filename = ui_dir + "index.html" + filename = ui_dir.joinpath("index.html") with open(filename) as f: content = f.read() From d1eb37ec779b01376d5ed3189fcf588de43d0080 Mon Sep 17 00:00:00 2001 From: Achal Shah Date: Fri, 20 Oct 2023 10:36:41 -0700 Subject: [PATCH 057/113] fix: Update jackson and remove unnecessary logging (#3809) Signed-off-by: Achal Shah Signed-off-by: Attila Toth --- java/pom.xml | 2 +- .../feast/serving/service/config/ServingServiceV2Module.java | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index 245d2d7cc6e..3a94e5f19c3 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -61,7 +61,7 @@ 1.5.24 3.14.7 3.10 - 2.12.6 + 2.14.0 2.3.1 1.3.2 2.0.1.Final diff --git a/java/serving/src/main/java/feast/serving/service/config/ServingServiceV2Module.java b/java/serving/src/main/java/feast/serving/service/config/ServingServiceV2Module.java index 564159ceed3..8beb91e4859 100644 --- a/java/serving/src/main/java/feast/serving/service/config/ServingServiceV2Module.java +++ b/java/serving/src/main/java/feast/serving/service/config/ServingServiceV2Module.java @@ -54,7 +54,6 @@ public ServingServiceV2 registryBasedServingServiceV2( break; case REDIS: RedisClientAdapter redisClient = RedisClient.create(store.getRedisConfig()); - log.info("Created EntityKeySerializerV2"); retriever = new RedisOnlineRetriever( applicationProperties.getFeast().getProject(), @@ -69,8 +68,6 @@ public ServingServiceV2 registryBasedServingServiceV2( store.getType())); } - log.info("Working Directory = " + System.getProperty("user.dir")); - final OnlineTransformationService onlineTransformationService = new OnlineTransformationService( applicationProperties.getFeast().getTransformationServiceEndpoint(), From 1b24b5da509199445aa3bd6f0ff3b4bd6992ea28 Mon Sep 17 00:00:00 2001 From: Achal Shah Date: Fri, 20 Oct 2023 13:45:06 -0700 Subject: [PATCH 058/113] chore: Add harry to CODEOWNERS (#3808) * chore: Add harry to CODEOWNERS Signed-off-by: Achal Shah * add path Signed-off-by: Achal Shah --------- Signed-off-by: Achal Shah Signed-off-by: Achal Shah Signed-off-by: Attila Toth --- CODEOWNERS | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 4eae6d35245..bb154a71481 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -10,9 +10,14 @@ # Core utils /sdk/python/feast/infra/offline_stores/offline_utils.py @feast-dev/maintainers @sfc-gh-madkins -# BigQuery +# Offline interfaces /sdk/python/feast/infra/offline_stores/offline_store.py @feast-dev/maintainers +# BigQuery +/sdk/python/feast/infra/offline_stores/bigquery.py @sudohainguyen +/sdk/python/feast/infra/offline_stores/bigquery_source.py @sudohainguyen +/sdk/python/tests/integration/feature_repos/universal/data_sources/bigquery.py @sudohainguyen + # Snowflake /sdk/python/feast/infra/offline_stores/snowflake* @sfc-gh-madkins @@ -27,6 +32,10 @@ # ==== Online Stores ==== +# HBase +/sdk/python/feast/infra/online_stores/hbase.py @sudohainguyen +/sdk/python/feast/infra/online_stores/contrib/hbase_online_store @sudohainguyen + # Redis /sdk/python/feast/infra/online_stores/redis.py @DvirDukhan /java/feast/serving/connectors/redis/ @DvirDukhan From dc1d3a182cbeb410089f58bfcbbe5485261fddc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 22:07:12 +0000 Subject: [PATCH 059/113] chore: Bump golang.org/x/net from 0.7.0 to 0.17.0 (#3792) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.7.0 to 0.17.0. - [Commits](https://github.com/golang/net/compare/v0.7.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- go.mod | 10 +++++----- go.sum | 26 ++++++++++++++++++-------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 68d47d70701..20c52d32212 100644 --- a/go.mod +++ b/go.mod @@ -37,11 +37,11 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4 // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.1.12 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + golang.org/x/tools v0.6.0 // indirect golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect diff --git a/go.sum b/go.sum index a2c7501e82b..990ff9b1ba5 100644 --- a/go.sum +++ b/go.sum @@ -895,6 +895,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -951,10 +952,10 @@ golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1017,8 +1018,10 @@ golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfS golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1059,6 +1062,7 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1144,13 +1148,17 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1163,8 +1171,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1236,10 +1246,10 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 9651d5f36d1896d00c7da7a5aef0f482239303e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:10:03 -0700 Subject: [PATCH 060/113] chore: Bump @babel/traverse from 7.17.10 to 7.23.2 in /sdk/python/feast/ui (#3802) chore: Bump @babel/traverse in /sdk/python/feast/ui Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.17.10 to 7.23.2. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse) --- updated-dependencies: - dependency-name: "@babel/traverse" dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/feast/ui/yarn.lock | 127 +++++++++++++++++----------------- 1 file changed, 63 insertions(+), 64 deletions(-) diff --git a/sdk/python/feast/ui/yarn.lock b/sdk/python/feast/ui/yarn.lock index 6fb431576ae..80a16dddcaa 100644 --- a/sdk/python/feast/ui/yarn.lock +++ b/sdk/python/feast/ui/yarn.lock @@ -26,12 +26,13 @@ dependencies: "@babel/highlight" "^7.16.7" -"@babel/code-frame@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" - integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== +"@babel/code-frame@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== dependencies: - "@babel/highlight" "^7.22.5" + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.17.0", "@babel/compat-data@^7.17.10": version "7.17.10" @@ -77,12 +78,12 @@ "@jridgewell/gen-mapping" "^0.1.0" jsesc "^2.5.1" -"@babel/generator@^7.22.7": - version "7.22.9" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" - integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== +"@babel/generator@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" + integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== dependencies: - "@babel/types" "^7.22.5" + "@babel/types" "^7.23.0" "@jridgewell/gen-mapping" "^0.3.2" "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" @@ -161,10 +162,10 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-environment-visitor@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" - integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== "@babel/helper-explode-assignable-expression@^7.16.7": version "7.16.7" @@ -181,13 +182,13 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.17.0" -"@babel/helper-function-name@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" - integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== dependencies: - "@babel/template" "^7.22.5" - "@babel/types" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" "@babel/helper-hoist-variables@^7.16.7": version "7.16.7" @@ -313,6 +314,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + "@babel/helper-validator-identifier@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" @@ -351,13 +357,13 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/highlight@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" - integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== dependencies: - "@babel/helper-validator-identifier" "^7.22.5" - chalk "^2.0.0" + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" js-tokens "^4.0.0" "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.10": @@ -365,10 +371,10 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.10.tgz#873b16db82a8909e0fbd7f115772f4b739f6ce78" integrity sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ== -"@babel/parser@^7.22.5", "@babel/parser@^7.22.7": - version "7.22.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" - integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== +"@babel/parser@^7.22.15", "@babel/parser@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": version "7.16.7" @@ -1135,44 +1141,28 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/template@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" - integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== dependencies: - "@babel/code-frame" "^7.22.5" - "@babel/parser" "^7.22.5" - "@babel/types" "^7.22.5" + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" -"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.10", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.10.tgz#1ee1a5ac39f4eac844e6cf855b35520e5eb6f8b5" - integrity sha512-VmbrTHQteIdUUQNTb+zE12SHS/xQVIShmBPhlNP12hD5poF2pbITW1Z4172d03HegaQWhLffdkRJYtAzp0AGcw== +"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.10", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" + integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.10" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.17.10" - "@babel/types" "^7.17.10" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.4.5": - version "7.22.8" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" - integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== - dependencies: - "@babel/code-frame" "^7.22.5" - "@babel/generator" "^7.22.7" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" "@babel/helper-hoist-variables" "^7.22.5" "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.22.7" - "@babel/types" "^7.22.5" + "@babel/parser" "^7.23.0" + "@babel/types" "^7.23.0" debug "^4.1.0" globals "^11.1.0" @@ -1184,6 +1174,15 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@babel/types@^7.22.15", "@babel/types@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" + integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + "@babel/types@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" @@ -3690,7 +3689,7 @@ ccount@^1.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== -chalk@^2.0.0, chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== From 874cc5b1dcbd7ada522486ccea44ece5aaa1027e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 22:12:58 +0000 Subject: [PATCH 061/113] chore: Bump avro from 1.10.0 to 1.11.3 in /sdk/python/requirements (#3780) Bumps [avro](https://github.com/apache/avro) from 1.10.0 to 1.11.3. - [Release notes](https://github.com/apache/avro/releases) - [Commits](https://github.com/apache/avro/compare/release-1.10.0...release-1.11.3) --- updated-dependencies: - dependency-name: avro dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/requirements/py3.10-ci-requirements.txt | 2 +- sdk/python/requirements/py3.8-ci-requirements.txt | 2 +- sdk/python/requirements/py3.9-ci-requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index 46b6303a907..7e36d414ca6 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -56,7 +56,7 @@ attrs==23.1.0 # bowler # jsonschema # referencing -avro==1.10.0 +avro==1.11.3 # via feast (setup.py) azure-core==1.29.4 # via diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index 01190cef29a..a6bfb313ba2 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -56,7 +56,7 @@ attrs==23.1.0 # bowler # jsonschema # referencing -avro==1.10.0 +avro==1.11.3 # via feast (setup.py) azure-core==1.29.3 # via diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index eabc2c0b8f1..f9181ea94cd 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -56,7 +56,7 @@ attrs==23.1.0 # bowler # jsonschema # referencing -avro==1.10.0 +avro==1.11.3 # via feast (setup.py) azure-core==1.29.4 # via From c1513c16476356de2b06d9eb67682abe4e8c665c Mon Sep 17 00:00:00 2001 From: Harry Date: Sat, 21 Oct 2023 05:13:49 +0700 Subject: [PATCH 062/113] feat: Support GCS filesystem for bytewax engine (#3774) * fix: Support param timeout when persisting Signed-off-by: Hai Nguyen * fix: fix java integration test Signed-off-by: Hai Nguyen --------- Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- .../contrib/bytewax/bytewax_materialization_dataflow.py | 4 +--- setup.py | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py index bf5229303ab..fe2a7f35c17 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py @@ -2,7 +2,6 @@ import pyarrow as pa import pyarrow.parquet as pq -import s3fs from bytewax.dataflow import Dataflow # type: ignore from bytewax.execution import cluster_main from bytewax.inputs import ManualInputConfig, distribute @@ -29,8 +28,7 @@ def __init__( self._run_dataflow() def process_path(self, path): - fs = s3fs.S3FileSystem() - dataset = pq.ParquetDataset(path, filesystem=fs, use_legacy_dataset=False) + dataset = pq.ParquetDataset(path, use_legacy_dataset=False) batches = [] for fragment in dataset.fragments: for batch in fragment.to_table().to_batches(): diff --git a/setup.py b/setup.py index 047100f03eb..9fbc2bc2cd8 100644 --- a/setup.py +++ b/setup.py @@ -91,6 +91,7 @@ "google-cloud-datastore>=2.1.0,<3", "google-cloud-storage>=1.34.0,<3", "google-cloud-bigtable>=2.11.0,<3", + "gcsfs", ] REDIS_REQUIRED = [ @@ -158,7 +159,7 @@ "moto", "mypy>=0.981,<0.990", "avro==1.10.0", - "gcsfs>=0.4.0,<=2022.01.0", + "gcsfs", "urllib3>=1.25.4,<2", "psutil==5.9.0", "py>=1.11.0", # https://github.com/pytest-dev/pytest/issues/10420 From 4c2d7f5904eb1d2ec8c47a897ef2f5ff11d99ca7 Mon Sep 17 00:00:00 2001 From: Harry Date: Sat, 21 Oct 2023 05:14:06 +0700 Subject: [PATCH 063/113] feat: Make bytewax job write as mini-batches (#3777) Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- .../bytewax_materialization_dataflow.py | 23 +++++++++++++++---- .../bytewax/bytewax_materialization_engine.py | 7 ++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py index fe2a7f35c17..e9d6a756b2c 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py @@ -1,3 +1,4 @@ +import os from typing import List import pyarrow as pa @@ -11,6 +12,8 @@ from feast import FeatureStore, FeatureView, RepoConfig from feast.utils import _convert_arrow_to_proto, _run_pyarrow_field_mapping +DEFAULT_BATCH_SIZE = 1000 + class BytewaxMaterializationDataflow: def __init__( @@ -44,6 +47,11 @@ def input_builder(self, worker_index, worker_count, _state): return def output_builder(self, worker_index, worker_count): + def yield_batch(iterable, batch_size): + """Yield mini-batches from an iterable.""" + for i in range(0, len(iterable), batch_size): + yield iterable[i : i + batch_size] + def output_fn(batch): table = pa.Table.from_batches([batch]) @@ -62,12 +70,17 @@ def output_fn(batch): ) provider = self.feature_store._get_provider() with tqdm(total=len(rows_to_write)) as progress: - provider.online_write_batch( - config=self.config, - table=self.feature_view, - data=rows_to_write, - progress=progress.update, + # break rows_to_write to mini-batches + batch_size = int( + os.getenv("BYTEWAX_MINI_BATCH_SIZE", DEFAULT_BATCH_SIZE) ) + for mini_batch in yield_batch(rows_to_write, batch_size): + provider.online_write_batch( + config=self.config, + table=self.feature_view, + data=mini_batch, + progress=progress.update, + ) return output_fn diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py index 21b7a5da1fa..787dd585ff2 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py @@ -67,6 +67,9 @@ class BytewaxMaterializationEngineConfig(FeastConfigBaseModel): max_parallelism: int = 10 """ (optional) Maximum number of pods (default 10) allowed to run in parallel per job""" + mini_batch_size: int = 1000 + """ (optional) Number of rows to process per write operation (default 1000)""" + class BytewaxMaterializationEngine(BatchMaterializationEngine): def __init__( @@ -254,6 +257,10 @@ def _create_job_definition(self, job_id, namespace, pods, env): "name": "BYTEWAX_STATEFULSET_NAME", "value": f"dataflow-{job_id}", }, + { + "name": "BYTEWAX_MINI_BATCH_SIZE", + "value": str(self.batch_engine_config.mini_batch_size), + }, ] # Add any Feast configured environment variables job_env.extend(env) From 8cd9045c0e0b603b3186a226f9e07da08559ee85 Mon Sep 17 00:00:00 2001 From: Harry Date: Sat, 21 Oct 2023 05:14:47 +0700 Subject: [PATCH 064/113] fix: Resolve hbase hotspot issue when materializing (#3790) * fix: Resolve hbase hotspot issue when materializing Signed-off-by: Hai Nguyen * chore: Refactor internal table id generator Signed-off-by: Hai Nguyen --------- Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- .../contrib/hbase_online_store/hbase.py | 72 +++++++++++++------ 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/sdk/python/feast/infra/online_stores/contrib/hbase_online_store/hbase.py b/sdk/python/feast/infra/online_stores/contrib/hbase_online_store/hbase.py index aff0c6c42c5..2636cf95e23 100644 --- a/sdk/python/feast/infra/online_stores/contrib/hbase_online_store/hbase.py +++ b/sdk/python/feast/infra/online_stores/contrib/hbase_online_store/hbase.py @@ -8,7 +8,7 @@ from feast import Entity from feast.feature_view import FeatureView -from feast.infra.key_encoding_utils import serialize_entity_key +from feast.infra.online_stores.helpers import compute_entity_id from feast.infra.online_stores.online_store import OnlineStore from feast.infra.utils.hbase_utils import HbaseConstants, HbaseUtils from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto @@ -104,14 +104,15 @@ def online_write_batch( hbase = HbaseUtils(self._get_conn(config)) project = config.project - table_name = _table_id(project, table) + table_name = self._table_id(project, table) b = hbase.batch(table_name) for entity_key, values, timestamp, created_ts in data: - row_key = serialize_entity_key( + row_key = self._hbase_row_key( entity_key, - entity_key_serialization_version=config.entity_key_serialization_version, - ).hex() + feature_view_name=table.name, + config=config, + ) values_dict = {} for feature_name, val in values.items(): values_dict[ @@ -133,6 +134,9 @@ def online_write_batch( b.put(row_key, values_dict) b.send() + if progress: + progress(len(data)) + @log_exceptions_and_usage(online_store="hbase") def online_read( self, @@ -152,15 +156,16 @@ def online_read( """ hbase = HbaseUtils(self._get_conn(config)) project = config.project - table_name = _table_id(project, table) + table_name = self._table_id(project, table) result: List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]] = [] row_keys = [ - serialize_entity_key( + self._hbase_row_key( entity_key, - entity_key_serialization_version=config.entity_key_serialization_version, - ).hex() + feature_view_name=table.name, + config=config, + ) for entity_key in entity_keys ] rows = hbase.rows(table_name, row_keys=row_keys) @@ -206,12 +211,12 @@ def update( # We don't create any special state for the entites in this implementation. for table in tables_to_keep: - table_name = _table_id(project, table) + table_name = self._table_id(project, table) if not hbase.check_if_table_exist(table_name): hbase.create_table_with_default_cf(table_name) for table in tables_to_delete: - table_name = _table_id(project, table) + table_name = self._table_id(project, table) hbase.delete_table(table_name) def teardown( @@ -231,16 +236,43 @@ def teardown( project = config.project for table in tables: - table_name = _table_id(project, table) + table_name = self._table_id(project, table) hbase.delete_table(table_name) + def _hbase_row_key( + self, + entity_key: EntityKeyProto, + feature_view_name: str, + config: RepoConfig, + ) -> bytes: + """ + Computes the HBase row key for a given entity key and feature view name. -def _table_id(project: str, table: FeatureView) -> str: - """ - Returns table name given the project_name and the feature_view. + Args: + entity_key (EntityKeyProto): The entity key to compute the row key for. + feature_view_name (str): The name of the feature view to compute the row key for. + config (RepoConfig): The configuration for the Feast repository. - Args: - project: Name of the feast project. - table: Feast FeatureView. - """ - return f"{project}_{table.name}" + Returns: + bytes: The HBase row key for the given entity key and feature view name. + """ + entity_id = compute_entity_id( + entity_key, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + # Even though `entity_id` uniquely identifies an entity, we use the same table + # for multiple feature_views with the same set of entities. + # To uniquely identify the row for a feature_view, we suffix the name of the feature_view itself. + # This also ensures that features for entities from various feature_views are + # colocated. + return f"{entity_id}#{feature_view_name}".encode() + + def _table_id(self, project: str, table: FeatureView) -> str: + """ + Returns table name given the project_name and the feature_view. + + Args: + project: Name of the feast project. + table: Feast FeatureView. + """ + return f"{project}:{table.name}" From 012e8996e74a93f3654113bec4561a492c6b6c8a Mon Sep 17 00:00:00 2001 From: Miedviediev Dmytro Date: Sat, 21 Oct 2023 01:15:40 +0300 Subject: [PATCH 065/113] fix: Make generated temp table name escaped (#3797) * Fix critical issue with saving results in BigQuery Need to encapsulate table path as tmp table path can contain symbols that can't be process by BigQuery without encapsulation Signed-off-by: Dmytro Miedviediev * update numpy Signed-off-by: Dmytro Miedviediev * revert numpy version Signed-off-by: Dmytro Miedviediev --------- Signed-off-by: Dmytro Miedviediev Signed-off-by: Attila Toth --- sdk/python/feast/infra/offline_stores/bigquery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/feast/infra/offline_stores/bigquery.py b/sdk/python/feast/infra/offline_stores/bigquery.py index 86c587c7fd2..10c8aa783fb 100644 --- a/sdk/python/feast/infra/offline_stores/bigquery.py +++ b/sdk/python/feast/infra/offline_stores/bigquery.py @@ -515,7 +515,7 @@ def to_bigquery( temp_dest_table = f"{tmp_dest['projectId']}.{tmp_dest['datasetId']}.{tmp_dest['tableId']}" # persist temp table - sql = f"CREATE TABLE `{dest}` AS SELECT * FROM {temp_dest_table}" + sql = f"CREATE TABLE `{dest}` AS SELECT * FROM `{temp_dest_table}`" self._execute_query(sql, timeout=timeout) print(f"Done writing to '{dest}'.") From 7285d5413e7ab1f02757b0c1c9c3f02b63055843 Mon Sep 17 00:00:00 2001 From: Harry Date: Sun, 22 Oct 2023 02:28:30 +0700 Subject: [PATCH 066/113] fix: Adopt connection pooling for HBase (#3793) Signed-off-by: Attila Toth --- sdk/python/feast/feature_store.py | 6 +- .../contrib/hbase_online_store/hbase.py | 55 ++++---- sdk/python/feast/infra/utils/hbase_utils.py | 127 +++++++++++------- 3 files changed, 107 insertions(+), 81 deletions(-) diff --git a/sdk/python/feast/feature_store.py b/sdk/python/feast/feature_store.py index 70f7d3dcb70..4b8200d96f5 100644 --- a/sdk/python/feast/feature_store.py +++ b/sdk/python/feast/feature_store.py @@ -287,7 +287,11 @@ def _list_feature_views( for fv in self._registry.list_feature_views( self.project, allow_cache=allow_cache ): - if hide_dummy_entity and fv.entities[0] == DUMMY_ENTITY_NAME: + if ( + hide_dummy_entity + and fv.entities + and fv.entities[0] == DUMMY_ENTITY_NAME + ): fv.entities = [] fv.entity_columns = [] feature_views.append(fv) diff --git a/sdk/python/feast/infra/online_stores/contrib/hbase_online_store/hbase.py b/sdk/python/feast/infra/online_stores/contrib/hbase_online_store/hbase.py index 2636cf95e23..1da9de89a81 100644 --- a/sdk/python/feast/infra/online_stores/contrib/hbase_online_store/hbase.py +++ b/sdk/python/feast/infra/online_stores/contrib/hbase_online_store/hbase.py @@ -3,14 +3,16 @@ from datetime import datetime from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple -from happybase import Connection +from happybase import ConnectionPool +from happybase.connection import DEFAULT_PROTOCOL, DEFAULT_TRANSPORT +from pydantic import StrictStr from pydantic.typing import Literal from feast import Entity from feast.feature_view import FeatureView from feast.infra.online_stores.helpers import compute_entity_id from feast.infra.online_stores.online_store import OnlineStore -from feast.infra.utils.hbase_utils import HbaseConstants, HbaseUtils +from feast.infra.utils.hbase_utils import HBaseConnector, HbaseConstants from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto from feast.protos.feast.types.Value_pb2 import Value as ValueProto from feast.repo_config import FeastConfigBaseModel, RepoConfig @@ -23,35 +25,20 @@ class HbaseOnlineStoreConfig(FeastConfigBaseModel): type: Literal["hbase"] = "hbase" """Online store type selector""" - host: str + host: StrictStr """Hostname of Hbase Thrift server""" - port: str + port: StrictStr """Port in which Hbase Thrift server is running""" + connection_pool_size: int = 4 + """Number of connections to Hbase Thrift server to keep in the connection pool""" -class HbaseConnection: - """ - Hbase connecttion to connect to hbase. - - Attributes: - store_config: Online store config for Hbase store. - """ + protocol: StrictStr = DEFAULT_PROTOCOL + """Protocol used to communicate with Hbase Thrift server""" - def __init__(self, store_config: HbaseOnlineStoreConfig): - self._store_config = store_config - self._real_conn = Connection( - host=store_config.host, port=int(store_config.port) - ) - - @property - def real_conn(self) -> Connection: - """Stores the real happybase Connection to connect to hbase.""" - return self._real_conn - - def close(self) -> None: - """Close the happybase connection.""" - self.real_conn.close() + transport: StrictStr = DEFAULT_TRANSPORT + """Transport used to communicate with Hbase Thrift server""" class HbaseOnlineStore(OnlineStore): @@ -62,7 +49,7 @@ class HbaseOnlineStore(OnlineStore): _conn: Happybase Connection to connect to hbase thrift server. """ - _conn: Connection = None + _conn: ConnectionPool = None def _get_conn(self, config: RepoConfig): """ @@ -76,7 +63,13 @@ def _get_conn(self, config: RepoConfig): assert isinstance(store_config, HbaseOnlineStoreConfig) if not self._conn: - self._conn = Connection(host=store_config.host, port=int(store_config.port)) + self._conn = ConnectionPool( + host=store_config.host, + port=int(store_config.port), + size=int(store_config.connection_pool_size), + protocol=store_config.protocol, + transport=store_config.transport, + ) return self._conn @log_exceptions_and_usage(online_store="hbase") @@ -102,7 +95,7 @@ def online_write_batch( the online store. Can be used to display progress. """ - hbase = HbaseUtils(self._get_conn(config)) + hbase = HBaseConnector(self._get_conn(config)) project = config.project table_name = self._table_id(project, table) @@ -154,7 +147,7 @@ def online_read( entity_keys: a list of entity keys that should be read from the FeatureStore. requested_features: a list of requested feature names. """ - hbase = HbaseUtils(self._get_conn(config)) + hbase = HBaseConnector(self._get_conn(config)) project = config.project table_name = self._table_id(project, table) @@ -206,7 +199,7 @@ def update( tables_to_delete: Tables to delete from the Hbase Online Store. tables_to_keep: Tables to keep in the Hbase Online Store. """ - hbase = HbaseUtils(self._get_conn(config)) + hbase = HBaseConnector(self._get_conn(config)) project = config.project # We don't create any special state for the entites in this implementation. @@ -232,7 +225,7 @@ def teardown( config: The RepoConfig for the current FeatureStore. tables: Tables to delete from the feature repo. """ - hbase = HbaseUtils(self._get_conn(config)) + hbase = HBaseConnector(self._get_conn(config)) project = config.project for table in tables: diff --git a/sdk/python/feast/infra/utils/hbase_utils.py b/sdk/python/feast/infra/utils/hbase_utils.py index 4816a60087c..d44f93f1619 100644 --- a/sdk/python/feast/infra/utils/hbase_utils.py +++ b/sdk/python/feast/infra/utils/hbase_utils.py @@ -1,9 +1,6 @@ from typing import List -from happybase import Connection - -from feast.infra.key_encoding_utils import serialize_entity_key -from feast.protos.feast.types.EntityKey_pb2 import EntityKey +from happybase import ConnectionPool class HbaseConstants: @@ -28,7 +25,7 @@ def get_col_from_feature(feature): return HbaseConstants.DEFAULT_COLUMN_FAMILY + ":" + feature -class HbaseUtils: +class HBaseConnector: """ Utils class to manage different Hbase operations. @@ -40,14 +37,22 @@ class HbaseUtils: """ def __init__( - self, conn: Connection = None, host: str = None, port: int = None, timeout=None + self, + pool: ConnectionPool = None, + host: str = None, + port: int = None, + connection_pool_size: int = 4, ): - if conn is None: + if pool is None: self.host = host self.port = port - self.conn = Connection(host=host, port=port, timeout=timeout) + self.pool = ConnectionPool( + host=host, + port=port, + size=connection_pool_size, + ) else: - self.conn = conn + self.pool = pool def create_table(self, table_name: str, colm_family: List[str]): """ @@ -60,7 +65,9 @@ def create_table(self, table_name: str, colm_family: List[str]): cf_dict: dict = {} for cf in colm_family: cf_dict[cf] = dict() - return self.conn.create_table(table_name, cf_dict) + + with self.pool.connection() as conn: + return conn.create_table(table_name, cf_dict) def create_table_with_default_cf(self, table_name: str): """ @@ -69,7 +76,8 @@ def create_table_with_default_cf(self, table_name: str): Arguments: table_name: Name of the Hbase table. """ - return self.conn.create_table(table_name, {"default": dict()}) + with self.pool.connection() as conn: + return conn.create_table(table_name, {"default": dict()}) def check_if_table_exist(self, table_name: str): """ @@ -78,16 +86,18 @@ def check_if_table_exist(self, table_name: str): Arguments: table_name: Name of the Hbase table. """ - return bytes(table_name, "utf-8") in self.conn.tables() + with self.pool.connection() as conn: + return bytes(table_name, "utf-8") in conn.tables() def batch(self, table_name: str): """ - Returns a 'Batch' instance that can be used for mass data manipulation in the hbase table. + Returns a "Batch" instance that can be used for mass data manipulation in the hbase table. Arguments: table_name: Name of the Hbase table. """ - return self.conn.table(table_name).batch() + with self.pool.connection() as conn: + return conn.table(table_name).batch() def put(self, table_name: str, row_key: str, data: dict): """ @@ -98,8 +108,9 @@ def put(self, table_name: str, row_key: str, data: dict): row_key: Row key of the row to be inserted to hbase table. data: Mapping of column family name:column name to column values """ - table = self.conn.table(table_name) - table.put(row_key, data) + with self.pool.connection() as conn: + table = conn.table(table_name) + table.put(row_key, data) def row( self, @@ -119,8 +130,9 @@ def row( timestamp: timestamp specifies the maximum version the cells can have. include_timestamp: specifies if (column, timestamp) to be return instead of only column. """ - table = self.conn.table(table_name) - return table.row(row_key, columns, timestamp, include_timestamp) + with self.pool.connection() as conn: + table = conn.table(table_name) + return table.row(row_key, columns, timestamp, include_timestamp) def rows( self, @@ -140,52 +152,69 @@ def rows( timestamp: timestamp specifies the maximum version the cells can have. include_timestamp: specifies if (column, timestamp) to be return instead of only column. """ - table = self.conn.table(table_name) - return table.rows(row_keys, columns, timestamp, include_timestamp) + with self.pool.connection() as conn: + table = conn.table(table_name) + return table.rows(row_keys, columns, timestamp, include_timestamp) def print_table(self, table_name): """Prints the table scanning all the rows of the hbase table.""" - table = self.conn.table(table_name) - scan_data = table.scan() - for row_key, cols in scan_data: - print(row_key.decode("utf-8"), cols) + with self.pool.connection() as conn: + table = conn.table(table_name) + scan_data = table.scan() + for row_key, cols in scan_data: + print(row_key.decode("utf-8"), cols) def delete_table(self, table: str): """Deletes the hbase table given the table name.""" if self.check_if_table_exist(table): - self.conn.delete_table(table, disable=True) + with self.pool.connection() as conn: + conn.delete_table(table, disable=True) def close_conn(self): """Closes the happybase connection.""" - self.conn.close() + with self.pool.connection() as conn: + conn.close() def main(): + from feast.infra.key_encoding_utils import serialize_entity_key + from feast.protos.feast.types.EntityKey_pb2 import EntityKey from feast.protos.feast.types.Value_pb2 import Value - connection = Connection(host="localhost", port=9090) - table = connection.table("test_hbase_driver_hourly_stats") - row_keys = [ - serialize_entity_key( - EntityKey(join_keys=["driver_id"], entity_values=[Value(int64_val=1004)]), - entity_key_serialization_version=2, - ).hex(), - serialize_entity_key( - EntityKey(join_keys=["driver_id"], entity_values=[Value(int64_val=1005)]), - entity_key_serialization_version=2, - ).hex(), - serialize_entity_key( - EntityKey(join_keys=["driver_id"], entity_values=[Value(int64_val=1024)]), - entity_key_serialization_version=2, - ).hex(), - ] - rows = table.rows(row_keys) - - for row_key, row in rows: - for key, value in row.items(): - col_name = bytes.decode(key, "utf-8").split(":")[1] - print(col_name, value) - print() + pool = ConnectionPool( + host="localhost", + port=9090, + size=2, + ) + with pool.connection() as connection: + table = connection.table("test_hbase_driver_hourly_stats") + row_keys = [ + serialize_entity_key( + EntityKey( + join_keys=["driver_id"], entity_values=[Value(int64_val=1004)] + ), + entity_key_serialization_version=2, + ).hex(), + serialize_entity_key( + EntityKey( + join_keys=["driver_id"], entity_values=[Value(int64_val=1005)] + ), + entity_key_serialization_version=2, + ).hex(), + serialize_entity_key( + EntityKey( + join_keys=["driver_id"], entity_values=[Value(int64_val=1024)] + ), + entity_key_serialization_version=2, + ).hex(), + ] + rows = table.rows(row_keys) + + for _, row in rows: + for key, value in row.items(): + col_name = bytes.decode(key, "utf-8").split(":")[1] + print(col_name, value) + print() if __name__ == "__main__": From 75dbaef17f6378c34797137e8175f64665b1b423 Mon Sep 17 00:00:00 2001 From: James Crabtree <77012363+james-crabtree-sp@users.noreply.github.com> Date: Tue, 24 Oct 2023 23:54:40 -0600 Subject: [PATCH 067/113] fix: Redundant feature materialization and premature incremental materialization timestamp updates (#3789) * SAASMLOPS-767 wait for jobs to complete Signed-off-by: James Crabtree * SAASMLOPS-805 Stopgap change to fix duplicate materialization of data Signed-off-by: James Crabtree * SAASMLOPS-805 save BYTEWAX_REPLICAS=1 Signed-off-by: James Crabtree * SAASMLOPS-809 fix bytewax workers so they only process a single file (#6) * SAASMLOPS-809 fix bytewax workers so they only process a single file * SAASMLOPS-809 fix newlines Signed-off-by: James Crabtree * SAASMLOPS-833 add configurable job timeout (#7) * SAASMLOPS-833 add configurable job timeout * SAASMLOPS-833 fix whitespace Signed-off-by: James Crabtree * develop Run large materializations in batches of pods Signed-off-by: James Crabtree * master Set job_batch_size at least equal to max_parallelism Signed-off-by: James Crabtree * master clarity max_parallelism description Signed-off-by: James Crabtree * master resolve bug that causes materialization to continue after job error Signed-off-by: James Crabtree * master resolve bug causing pod logs to not be printed Signed-off-by: James Crabtree --------- Signed-off-by: James Crabtree Signed-off-by: Attila Toth --- .../contrib/bytewax/Dockerfile | 2 +- .../bytewax_materialization_dataflow.py | 10 +- .../bytewax/bytewax_materialization_engine.py | 134 ++++++++++++++++-- .../bytewax/bytewax_materialization_job.py | 9 +- .../contrib/bytewax/dataflow.py | 3 + 5 files changed, 139 insertions(+), 19 deletions(-) diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/Dockerfile b/sdk/python/feast/infra/materialization/contrib/bytewax/Dockerfile index 963924f38d8..a26661ead35 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/Dockerfile +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/Dockerfile @@ -25,5 +25,5 @@ COPY README.md README.md # git dir to infer the version of feast we're installing. # https://github.com/pypa/setuptools_scm#usage-from-docker # I think it also assumes that this dockerfile is being built from the root of the directory. -RUN --mount=source=.git,target=.git,type=bind pip3 install --no-cache-dir -e '.[aws,gcp,bytewax]' +RUN --mount=source=.git,target=.git,type=bind pip3 install --no-cache-dir '.[aws,gcp,bytewax,snowflake]' diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py index e9d6a756b2c..31be7a6b893 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py @@ -5,7 +5,7 @@ import pyarrow.parquet as pq from bytewax.dataflow import Dataflow # type: ignore from bytewax.execution import cluster_main -from bytewax.inputs import ManualInputConfig, distribute +from bytewax.inputs import ManualInputConfig from bytewax.outputs import ManualOutputConfig from tqdm import tqdm @@ -21,11 +21,13 @@ def __init__( config: RepoConfig, feature_view: FeatureView, paths: List[str], + worker_index: int, ): self.config = config self.feature_store = FeatureStore(config=config) self.feature_view = feature_view + self.worker_index = worker_index self.paths = paths self._run_dataflow() @@ -40,11 +42,7 @@ def process_path(self, path): return batches def input_builder(self, worker_index, worker_count, _state): - worker_paths = distribute(self.paths, worker_index, worker_count) - for path in worker_paths: - yield None, path - - return + return [(None, self.paths[self.worker_index])] def output_builder(self, worker_index, worker_count): def yield_batch(iterable, batch_size): diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py index 787dd585ff2..1c9dc6a6bef 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py @@ -1,11 +1,14 @@ +import logging import uuid from datetime import datetime +from time import sleep from typing import Callable, List, Literal, Sequence, Union import yaml from kubernetes import client from kubernetes import config as k8s_config from kubernetes import utils +from kubernetes.client.exceptions import ApiException from kubernetes.utils import FailToCreateError from pydantic import StrictStr from tqdm import tqdm @@ -16,6 +19,7 @@ from feast.infra.materialization.batch_materialization_engine import ( BatchMaterializationEngine, MaterializationJob, + MaterializationJobStatus, MaterializationTask, ) from feast.infra.offline_stores.offline_store import OfflineStore @@ -27,6 +31,8 @@ from .bytewax_materialization_job import BytewaxMaterializationJob +logger = logging.getLogger(__name__) + class BytewaxMaterializationEngineConfig(FeastConfigBaseModel): """Batch Materialization Engine config for Bytewax""" @@ -65,11 +71,26 @@ class BytewaxMaterializationEngineConfig(FeastConfigBaseModel): """ (optional) additional labels to append to kubernetes objects """ max_parallelism: int = 10 - """ (optional) Maximum number of pods (default 10) allowed to run in parallel per job""" + """ (optional) Maximum number of pods allowed to run in parallel""" + + synchronous: bool = False + """ (optional) If true, wait for materialization for one feature to complete before moving to the next """ + + retry_limit: int = 2 + """ (optional) Maximum number of times to retry a materialization worker pod""" mini_batch_size: int = 1000 """ (optional) Number of rows to process per write operation (default 1000)""" + active_deadline_seconds: int = 86400 + """ (optional) Maximum amount of time a materialization job is allowed to run""" + + job_batch_size: int = 100 + """ (optional) Maximum number of pods to process per job. Only applies to synchronous materialization""" + + print_pod_logs_on_failure: bool = True + """(optional) Print pod logs on job failure. Only applies to synchronous materialization""" + class BytewaxMaterializationEngine(BatchMaterializationEngine): def __init__( @@ -173,8 +194,98 @@ def _materialize_one( ) paths = offline_job.to_remote_storage() + if self.batch_engine_config.synchronous: + offset = 0 + total_pods = len(paths) + batch_size = self.batch_engine_config.job_batch_size + if batch_size < 1: + raise ValueError("job_batch_size must be a value greater than 0") + if batch_size < self.batch_engine_config.max_parallelism: + logger.warning( + "job_batch_size is less than max_parallelism. Setting job_batch_size = max_parallelism" + ) + batch_size = self.batch_engine_config.max_parallelism + + while True: + next_offset = min(offset + batch_size, total_pods) + job = self._await_path_materialization( + paths[offset:next_offset], + feature_view, + offset, + next_offset, + total_pods, + ) + offset += batch_size + if ( + offset >= total_pods + or job.status() == MaterializationJobStatus.ERROR + ): + break + else: + job_id = str(uuid.uuid4()) + job = self._create_kubernetes_job(job_id, paths, feature_view) + + return job + + def _await_path_materialization( + self, paths, feature_view, batch_start, batch_end, total_pods + ): job_id = str(uuid.uuid4()) - return self._create_kubernetes_job(job_id, paths, feature_view) + job = self._create_kubernetes_job(job_id, paths, feature_view) + + try: + while job.status() in ( + MaterializationJobStatus.WAITING, + MaterializationJobStatus.RUNNING, + ): + logger.info( + f"{feature_view.name} materialization for pods {batch_start}-{batch_end} " + f"(of {total_pods}) running..." + ) + sleep(30) + logger.info( + f"{feature_view.name} materialization for pods {batch_start}-{batch_end} " + f"(of {total_pods}) complete with status {job.status()}" + ) + except BaseException as e: + logger.info(f"Deleting job {job.job_id()}") + try: + self.batch_v1.delete_namespaced_job(job.job_id(), self.namespace) + except ApiException as ae: + logger.warning(f"Could not delete job due to API Error: {ae.body}") + raise e + finally: + logger.info(f"Deleting configmap {self._configmap_name(job_id)}") + try: + self.v1.delete_namespaced_config_map( + self._configmap_name(job_id), self.namespace + ) + except ApiException as ae: + logger.warning( + f"Could not delete configmap due to API Error: {ae.body}" + ) + + if ( + job.status() == MaterializationJobStatus.ERROR + and self.batch_engine_config.print_pod_logs_on_failure + ): + self._print_pod_logs(job.job_id(), feature_view, batch_start) + + return job + + def _print_pod_logs(self, job_id, feature_view, offset=0): + pods_list = self.v1.list_namespaced_pod( + namespace=self.namespace, + label_selector=f"job-name={job_id}", + ).items + for i, pod in enumerate(pods_list): + logger.info(f"Logging output for {feature_view.name} pod {offset+i}") + try: + logger.info( + self.v1.read_namespaced_pod_log(pod.metadata.name, self.namespace) + ) + except ApiException as e: + logger.warning(f"Could not retrieve pod logs due to: {e.body}") def _create_kubernetes_job(self, job_id, paths, feature_view): try: @@ -210,7 +321,7 @@ def _create_configuration_map(self, job_id, paths, feature_view, namespace): "kind": "ConfigMap", "apiVersion": "v1", "metadata": { - "name": f"feast-{job_id}", + "name": self._configmap_name(job_id), "labels": {**labels, **self.batch_engine_config.labels}, }, "data": { @@ -223,7 +334,10 @@ def _create_configuration_map(self, job_id, paths, feature_view, namespace): body=configmap_manifest, ) - def _create_job_definition(self, job_id, namespace, pods, env): + def _configmap_name(self, job_id): + return f"feast-{job_id}" + + def _create_job_definition(self, job_id, namespace, pods, env, index_offset=0): """Create a kubernetes job definition.""" job_env = [ {"name": "RUST_BACKTRACE", "value": "full"}, @@ -284,8 +398,10 @@ def _create_job_definition(self, job_id, namespace, pods, env): }, "spec": { "ttlSecondsAfterFinished": 3600, + "backoffLimit": self.batch_engine_config.retry_limit, "completions": pods, "parallelism": min(pods, self.batch_engine_config.max_parallelism), + "activeDeadlineSeconds": self.batch_engine_config.active_deadline_seconds, "completionMode": "Indexed", "template": { "metadata": { @@ -324,7 +440,7 @@ def _create_job_definition(self, job_id, namespace, pods, env): }, { "mountPath": "/var/feast/", - "name": f"feast-{job_id}", + "name": self._configmap_name(job_id), }, ], } @@ -355,7 +471,7 @@ def _create_job_definition(self, job_id, namespace, pods, env): {"mountPath": "/etc/bytewax", "name": "hostfile"}, { "mountPath": "/var/feast/", - "name": f"feast-{job_id}", + "name": self._configmap_name(job_id), }, ], } @@ -365,13 +481,13 @@ def _create_job_definition(self, job_id, namespace, pods, env): { "configMap": { "defaultMode": 420, - "name": f"feast-{job_id}", + "name": self._configmap_name(job_id), }, "name": "python-files", }, { - "configMap": {"name": f"feast-{job_id}"}, - "name": f"feast-{job_id}", + "configMap": {"name": self._configmap_name(job_id)}, + "name": self._configmap_name(job_id), }, ], }, diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_job.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_job.py index 77d2149eb5a..4105be90ee7 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_job.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_job.py @@ -36,10 +36,13 @@ def status(self): if job_status.completion_time is None: return MaterializationJobStatus.RUNNING elif job_status.failed is not None: + self._error = Exception(f"Job {self.job_id()} failed") return MaterializationJobStatus.ERROR - elif job_status.active is None and job_status.succeeded is not None: - if job_status.conditions[0].type == "Complete": - return MaterializationJobStatus.SUCCEEDED + elif job_status.active is None: + if job_status.completion_time is not None: + if job_status.conditions[0].type == "Complete": + return MaterializationJobStatus.SUCCEEDED + return MaterializationJobStatus.WAITING def should_be_retried(self): return False diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py b/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py index e3d95e2a75c..23cdc20ef36 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py @@ -1,3 +1,5 @@ +import os + import yaml from feast import FeatureStore, RepoConfig @@ -19,4 +21,5 @@ config, store.get_feature_view(bytewax_config["feature_view"]), bytewax_config["paths"], + int(os.environ["JOB_COMPLETION_INDEX"]), ) From ee0c7cba9bbde85cd965af2abf743e02dac74e67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Oct 2023 06:16:56 +0000 Subject: [PATCH 068/113] chore: Bump urllib3 from 1.26.16 to 1.26.18 in /sdk/python/requirements (#3803) Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.16 to 1.26.18. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.16...1.26.18) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/requirements/py3.10-ci-requirements.txt | 2 +- sdk/python/requirements/py3.10-requirements.txt | 2 +- sdk/python/requirements/py3.8-ci-requirements.txt | 2 +- sdk/python/requirements/py3.8-requirements.txt | 2 +- sdk/python/requirements/py3.9-ci-requirements.txt | 2 +- sdk/python/requirements/py3.9-requirements.txt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index 7e36d414ca6..616ec5a2288 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -1018,7 +1018,7 @@ uri-template==1.3.0 # via jsonschema uritemplate==4.1.1 # via google-api-python-client -urllib3==1.26.16 +urllib3==1.26.18 # via # botocore # docker diff --git a/sdk/python/requirements/py3.10-requirements.txt b/sdk/python/requirements/py3.10-requirements.txt index 9ee910bf009..f4cac316d22 100644 --- a/sdk/python/requirements/py3.10-requirements.txt +++ b/sdk/python/requirements/py3.10-requirements.txt @@ -204,7 +204,7 @@ typing-extensions==4.7.1 # pydantic # sqlalchemy2-stubs # uvicorn -urllib3==2.0.4 +urllib3==1.26.18 # via requests uvicorn[standard]==0.23.2 # via feast (setup.py) diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index a6bfb313ba2..b84305d92f3 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -1034,7 +1034,7 @@ uri-template==1.3.0 # via jsonschema uritemplate==4.1.1 # via google-api-python-client -urllib3==1.26.16 +urllib3==1.26.18 # via # botocore # docker diff --git a/sdk/python/requirements/py3.8-requirements.txt b/sdk/python/requirements/py3.8-requirements.txt index 4011ce804f7..ec4a9f5187f 100644 --- a/sdk/python/requirements/py3.8-requirements.txt +++ b/sdk/python/requirements/py3.8-requirements.txt @@ -210,7 +210,7 @@ typing-extensions==4.7.1 # sqlalchemy2-stubs # starlette # uvicorn -urllib3==2.0.4 +urllib3==1.26.18 # via requests uvicorn[standard]==0.23.2 # via feast (setup.py) diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index f9181ea94cd..aee80ca040d 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -1030,7 +1030,7 @@ uri-template==1.3.0 # via jsonschema uritemplate==4.1.1 # via google-api-python-client -urllib3==1.26.16 +urllib3==1.26.18 # via # botocore # docker diff --git a/sdk/python/requirements/py3.9-requirements.txt b/sdk/python/requirements/py3.9-requirements.txt index 432ac4cbe62..81a8afa699a 100644 --- a/sdk/python/requirements/py3.9-requirements.txt +++ b/sdk/python/requirements/py3.9-requirements.txt @@ -205,7 +205,7 @@ typing-extensions==4.7.1 # sqlalchemy2-stubs # starlette # uvicorn -urllib3==2.0.4 +urllib3==1.26.18 # via requests uvicorn[standard]==0.23.2 # via feast (setup.py) From bc7b584f5d57012339472a95c046dae2f80d09dd Mon Sep 17 00:00:00 2001 From: Harry Date: Wed, 1 Nov 2023 01:14:06 +0700 Subject: [PATCH 069/113] feat: Add get online feature rpc to gprc server (#3815) Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- protos/feast/serving/GrpcServer.proto | 11 +-- protos/feast/serving/ServingService.proto | 2 + sdk/python/feast/cli.py | 11 ++- sdk/python/feast/infra/contrib/grpc_server.py | 69 ++++++++++++++++--- sdk/python/feast/type_map.py | 17 +++-- 5 files changed, 90 insertions(+), 20 deletions(-) diff --git a/protos/feast/serving/GrpcServer.proto b/protos/feast/serving/GrpcServer.proto index cd0274c5c75..34edb4ebe9c 100644 --- a/protos/feast/serving/GrpcServer.proto +++ b/protos/feast/serving/GrpcServer.proto @@ -1,5 +1,7 @@ syntax = "proto3"; +import "feast/serving/ServingService.proto"; + message PushRequest { map features = 1; string stream_feature_view = 2; @@ -8,7 +10,7 @@ message PushRequest { } message PushResponse { - bool status = 1; + bool status = 1; } message WriteToOnlineStoreRequest { @@ -18,10 +20,11 @@ message WriteToOnlineStoreRequest { } message WriteToOnlineStoreResponse { - bool status = 1; + bool status = 1; } service GrpcFeatureServer { - rpc Push (PushRequest) returns (PushResponse) {}; - rpc WriteToOnlineStore (WriteToOnlineStoreRequest) returns (WriteToOnlineStoreResponse); + rpc Push (PushRequest) returns (PushResponse) {}; + rpc WriteToOnlineStore (WriteToOnlineStoreRequest) returns (WriteToOnlineStoreResponse); + rpc GetOnlineFeatures (feast.serving.GetOnlineFeaturesRequest) returns (feast.serving.GetOnlineFeaturesResponse); } \ No newline at end of file diff --git a/protos/feast/serving/ServingService.proto b/protos/feast/serving/ServingService.proto index 0eef3cd883c..154d850099f 100644 --- a/protos/feast/serving/ServingService.proto +++ b/protos/feast/serving/ServingService.proto @@ -105,6 +105,8 @@ message GetOnlineFeaturesResponse { repeated FieldStatus statuses = 2; repeated google.protobuf.Timestamp event_timestamps = 3; } + + bool status = 3; } message GetOnlineFeaturesResponseMetadata { diff --git a/sdk/python/feast/cli.py b/sdk/python/feast/cli.py index 3153f02e518..4cce8855f47 100644 --- a/sdk/python/feast/cli.py +++ b/sdk/python/feast/cli.py @@ -705,15 +705,24 @@ def serve_command( show_default=False, help="The maximum number of threads that can be used to execute the gRPC calls", ) +@click.option( + "--registry_ttl_sec", + "-r", + help="Number of seconds after which the registry is refreshed", + type=click.INT, + default=5, + show_default=True, +) @click.pass_context def listen_command( ctx: click.Context, address: str, max_workers: int, + registry_ttl_sec: int, ): """Start a gRPC feature server to ingest streaming features on given address""" store = create_feature_store(ctx) - server = get_grpc_server(address, store, max_workers) + server = get_grpc_server(address, store, max_workers, registry_ttl_sec) server.start() server.wait_for_termination() diff --git a/sdk/python/feast/infra/contrib/grpc_server.py b/sdk/python/feast/infra/contrib/grpc_server.py index 2017f1095b2..27ac45e77cc 100644 --- a/sdk/python/feast/infra/contrib/grpc_server.py +++ b/sdk/python/feast/infra/contrib/grpc_server.py @@ -1,12 +1,14 @@ import logging +import threading from concurrent import futures +from typing import Optional import grpc import pandas as pd from grpc_health.v1 import health, health_pb2_grpc from feast.data_source import PushMode -from feast.errors import PushSourceNotFoundException +from feast.errors import FeatureServiceNotFoundException, PushSourceNotFoundException from feast.feature_store import FeatureStore from feast.protos.feast.serving.GrpcServer_pb2 import ( PushResponse, @@ -16,6 +18,12 @@ GrpcFeatureServerServicer, add_GrpcFeatureServerServicer_to_server, ) +from feast.protos.feast.serving.ServingService_pb2 import ( + GetOnlineFeaturesRequest, + GetOnlineFeaturesResponse, +) + +logger = logging.getLogger(__name__) def parse(features): @@ -28,10 +36,16 @@ def parse(features): class GrpcFeatureServer(GrpcFeatureServerServicer): fs: FeatureStore - def __init__(self, fs: FeatureStore): + _shuting_down: bool = False + _active_timer: Optional[threading.Timer] = None + + def __init__(self, fs: FeatureStore, registry_ttl_sec: int = 5): self.fs = fs + self.registry_ttl_sec = registry_ttl_sec super().__init__() + self._async_refresh() + def Push(self, request, context): try: df = parse(request.features) @@ -53,19 +67,19 @@ def Push(self, request, context): to=to, ) except PushSourceNotFoundException as e: - logging.exception(str(e)) + logger.exception(str(e)) context.set_code(grpc.StatusCode.INVALID_ARGUMENT) context.set_details(str(e)) return PushResponse(status=False) except Exception as e: - logging.exception(str(e)) + logger.exception(str(e)) context.set_code(grpc.StatusCode.INTERNAL) context.set_details(str(e)) return PushResponse(status=False) return PushResponse(status=True) def WriteToOnlineStore(self, request, context): - logging.warning( + logger.warning( "write_to_online_store is deprecated. Please consider using Push instead" ) try: @@ -76,16 +90,55 @@ def WriteToOnlineStore(self, request, context): allow_registry_cache=request.allow_registry_cache, ) except Exception as e: - logging.exception(str(e)) + logger.exception(str(e)) context.set_code(grpc.StatusCode.INTERNAL) context.set_details(str(e)) return PushResponse(status=False) return WriteToOnlineStoreResponse(status=True) + def GetOnlineFeatures(self, request: GetOnlineFeaturesRequest, context): + if request.HasField("feature_service"): + logger.info(f"Requesting feature service: {request.feature_service}") + try: + features = self.fs.get_feature_service( + request.feature_service, allow_cache=True + ) + except FeatureServiceNotFoundException as e: + logger.error(f"Feature service {request.feature_service} not found") + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + return GetOnlineFeaturesResponse() + else: + features = list(request.features.val) + + result = self.fs._get_online_features( + features, + request.entities, + request.full_feature_names, + ).proto + + return result + + def _async_refresh(self): + self.fs.refresh_registry() + if self._shuting_down: + return + self._active_timer = threading.Timer(self.registry_ttl_sec, self._async_refresh) + self._active_timer.start() -def get_grpc_server(address: str, fs: FeatureStore, max_workers: int): + +def get_grpc_server( + address: str, + fs: FeatureStore, + max_workers: int, + registry_ttl_sec: int, +): + logger.info(f"Initializing gRPC server on {address}") server = grpc.server(futures.ThreadPoolExecutor(max_workers=max_workers)) - add_GrpcFeatureServerServicer_to_server(GrpcFeatureServer(fs), server) + add_GrpcFeatureServerServicer_to_server( + GrpcFeatureServer(fs, registry_ttl_sec=registry_ttl_sec), + server, + ) health_servicer = health.HealthServicer( experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=max_workers), diff --git a/sdk/python/feast/type_map.py b/sdk/python/feast/type_map.py index 3f490690669..cdb65f886e2 100644 --- a/sdk/python/feast/type_map.py +++ b/sdk/python/feast/type_map.py @@ -428,12 +428,15 @@ def _python_value_to_proto_value( for value in values ] if feast_value_type in PYTHON_SCALAR_VALUE_TYPE_TO_PROTO_VALUE: - return [ - ProtoValue(**{field_name: func(value)}) - if not pd.isnull(value) - else ProtoValue() - for value in values - ] + out = [] + for value in values: + if isinstance(value, ProtoValue): + out.append(value) + elif not pd.isnull(value): + out.append(ProtoValue(**{field_name: func(value)})) + else: + out.append(ProtoValue()) + return out raise Exception(f"Unsupported data type: ${str(type(values[0]))}") @@ -746,7 +749,7 @@ def spark_to_feast_value_type(spark_type_as_str: str) -> ValueType: "array": ValueType.UNIX_TIMESTAMP_LIST, } # TODO: Find better way of doing this. - if type(spark_type_as_str) != str or spark_type_as_str not in type_map: + if not isinstance(spark_type_as_str, str) or spark_type_as_str not in type_map: return ValueType.NULL return type_map[spark_type_as_str.lower()] From 57d2c633b0368368ff5364ddfee352b80f1feed2 Mon Sep 17 00:00:00 2001 From: Harry Date: Wed, 1 Nov 2023 01:14:42 +0700 Subject: [PATCH 070/113] fix: Add async refresh to prevent synchronous refresh in main thread (#3812) fix: Add async refresh to prevent synchronous refresh in main thread for http feature server Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- sdk/python/feast/cli.py | 10 +++++++++ sdk/python/feast/feature_server.py | 33 ++++++++++++++++++++++++++++-- sdk/python/feast/feature_store.py | 2 ++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/sdk/python/feast/cli.py b/sdk/python/feast/cli.py index 4cce8855f47..2eb2c27bcb7 100644 --- a/sdk/python/feast/cli.py +++ b/sdk/python/feast/cli.py @@ -663,6 +663,14 @@ def init_command(project_directory, minimal: bool, template: str): show_default=True, help="Timeout for keep alive", ) +@click.option( + "--registry_ttl_sec", + "-r", + help="Number of seconds after which the registry is refreshed", + type=click.INT, + default=5, + show_default=True, +) @click.pass_context def serve_command( ctx: click.Context, @@ -673,6 +681,7 @@ def serve_command( no_feature_log: bool, workers: int, keep_alive_timeout: int, + registry_ttl_sec: int = 5, ): """Start a feature server locally on a given port.""" store = create_feature_store(ctx) @@ -685,6 +694,7 @@ def serve_command( no_feature_log=no_feature_log, workers=workers, keep_alive_timeout=keep_alive_timeout, + registry_ttl_sec=registry_ttl_sec, ) diff --git a/sdk/python/feast/feature_server.py b/sdk/python/feast/feature_server.py index 7c638dd2481..618aefb2f28 100644 --- a/sdk/python/feast/feature_server.py +++ b/sdk/python/feast/feature_server.py @@ -1,4 +1,5 @@ import json +import threading import traceback import warnings from typing import List, Optional @@ -44,14 +45,37 @@ class MaterializeIncrementalRequest(BaseModel): feature_views: Optional[List[str]] = None -def get_app(store: "feast.FeatureStore"): +def get_app(store: "feast.FeatureStore", registry_ttl_sec: int = 5): proto_json.patch() app = FastAPI() + # Asynchronously refresh registry, notifying shutdown and canceling the active timer if the app is shutting down + registry_proto = None + shutting_down = False + active_timer: Optional[threading.Timer] = None async def get_body(request: Request): return await request.body() + def async_refresh(): + store.refresh_registry() + nonlocal registry_proto + registry_proto = store.registry.proto() + if shutting_down: + return + nonlocal active_timer + active_timer = threading.Timer(registry_ttl_sec, async_refresh) + active_timer.start() + + @app.on_event("shutdown") + def shutdown_event(): + nonlocal shutting_down + shutting_down = True + if active_timer: + active_timer.cancel() + + async_refresh() + @app.post("/get-online-features") def get_online_features(body=Depends(get_body)): try: @@ -180,7 +204,10 @@ def materialize_incremental(body=Depends(get_body)): class FeastServeApplication(gunicorn.app.base.BaseApplication): def __init__(self, store: "feast.FeatureStore", **options): - self._app = get_app(store=store) + self._app = get_app( + store=store, + registry_ttl_sec=options.get("registry_ttl_sec", 5), + ) self._options = options super().__init__() @@ -202,6 +229,7 @@ def start_server( no_access_log: bool, workers: int, keep_alive_timeout: int, + registry_ttl_sec: int = 5, ): FeastServeApplication( store=store, @@ -209,4 +237,5 @@ def start_server( accesslog=None if no_access_log else "-", workers=workers, keepalive=keep_alive_timeout, + registry_ttl_sec=registry_ttl_sec, ).run() diff --git a/sdk/python/feast/feature_store.py b/sdk/python/feast/feature_store.py index 4b8200d96f5..d3f98f80323 100644 --- a/sdk/python/feast/feature_store.py +++ b/sdk/python/feast/feature_store.py @@ -2228,6 +2228,7 @@ def serve( no_feature_log: bool, workers: int, keep_alive_timeout: int, + registry_ttl_sec: int, ) -> None: """Start the feature consumption server locally on a given port.""" type_ = type_.lower() @@ -2243,6 +2244,7 @@ def serve( no_access_log=no_access_log, workers=workers, keep_alive_timeout=keep_alive_timeout, + registry_ttl_sec=registry_ttl_sec, ) @log_exceptions_and_usage From 7611aa86f76e5c6c71ee381efa68afa10b4b4d86 Mon Sep 17 00:00:00 2001 From: Harry Date: Wed, 8 Nov 2023 08:38:58 +0700 Subject: [PATCH 071/113] fix: Bytewax engine create configmap from object (#3821) fix: bytewax engine create configmap from object Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- .../contrib/bytewax/bytewax_materialization_engine.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py index 1c9dc6a6bef..b2f8985f876 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py @@ -27,7 +27,7 @@ from feast.infra.registry.base_registry import BaseRegistry from feast.repo_config import FeastConfigBaseModel from feast.stream_feature_view import StreamFeatureView -from feast.utils import _get_column_names, get_default_yaml_file_path +from feast.utils import _get_column_names from .bytewax_materialization_job import BytewaxMaterializationJob @@ -307,10 +307,7 @@ def _create_kubernetes_job(self, job_id, paths, feature_view): def _create_configuration_map(self, job_id, paths, feature_view, namespace): """Create a Kubernetes configmap for this job""" - repo_path = self.repo_config.repo_path - assert repo_path - feature_store_path = get_default_yaml_file_path(repo_path) - feature_store_configuration = feature_store_path.read_text() + feature_store_configuration = yaml.dump(self.repo_config.dict()) materialization_config = yaml.dump( {"paths": paths, "feature_view": feature_view.name} From 84fdacfaff855aa2c72d1c8d96095c95fa7c6ea1 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Sat, 4 Nov 2023 15:35:04 +0700 Subject: [PATCH 072/113] fix: Set upper bound for bigquery client due to its breaking changes Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9fbc2bc2cd8..5084193d5ef 100644 --- a/setup.py +++ b/setup.py @@ -86,7 +86,7 @@ GCP_REQUIRED = [ "google-api-core>=1.23.0,<3", "googleapis-common-protos>=1.52.0,<2", - "google-cloud-bigquery[pandas]>=2,<4", + "google-cloud-bigquery[pandas]>=2,<3.13.0", "google-cloud-bigquery-storage >= 2.0.0,<3", "google-cloud-datastore>=2.1.0,<3", "google-cloud-storage>=1.34.0,<3", From 5fbc6adad601c420f3f69380a41e991b5ad2e5e1 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Wed, 8 Nov 2023 10:56:28 +0700 Subject: [PATCH 073/113] fix: update dependencies versions due to conflicts Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- setup.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/setup.py b/setup.py index 5084193d5ef..38b7d295a93 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,6 @@ from setuptools.command.install import install except ImportError: - from distutils.command.build_ext import build_ext as _build_ext from distutils.command.build_py import build_py from distutils.core import setup @@ -80,7 +79,7 @@ # FastAPI does not correctly pull starlette dependency on httpx see thread(https://github.com/tiangolo/fastapi/issues/5656). "httpx>=0.23.3", "importlib-resources>=6.0.0,<7", - "importlib_metadata>=6.8.0,<7" + "importlib_metadata>=6.8.0,<7", ] GCP_REQUIRED = [ @@ -91,7 +90,7 @@ "google-cloud-datastore>=2.1.0,<3", "google-cloud-storage>=1.34.0,<3", "google-cloud-bigtable>=2.11.0,<3", - "gcsfs", + "fsspec<2023.10.0", ] REDIS_REQUIRED = [ @@ -99,7 +98,7 @@ "hiredis>=2.0.0,<3", ] -AWS_REQUIRED = ["boto3>=1.17.0,<2", "docker>=5.0.2", "s3fs"] +AWS_REQUIRED = ["boto3>=1.17.0,<2", "docker>=5.0.2", "fsspec<2023.10.0"] BYTEWAX_REQUIRED = ["bytewax==0.15.1", "docker>=5.0.2", "kubernetes<=20.13.0"] @@ -159,8 +158,8 @@ "moto", "mypy>=0.981,<0.990", "avro==1.10.0", - "gcsfs", - "urllib3>=1.25.4,<2", + "fsspec<2023.10.0", + "urllib3>=1.25.4,<3", "psutil==5.9.0", "py>=1.11.0", # https://github.com/pytest-dev/pytest/issues/10420 "pytest>=6.0.0,<8", @@ -173,7 +172,6 @@ "pytest-mock==1.10.4", "Sphinx>4.0.0,<7", "testcontainers>=3.5,<4", - "adlfs==0.5.9", "firebase-admin>=5.2.0,<6", "pre-commit<3.3.2", "assertpy==1.1", @@ -184,10 +182,10 @@ "types-pytz", "types-PyYAML", "types-redis", - "types-requests", + "types-requests<2.31.0", "types-setuptools", "types-tabulate", - "virtualenv<20.24.2" + "virtualenv<20.24.2", ] + GCP_REQUIRED + REDIS_REQUIRED From a241834d4f2b7b88ca7e6b1315c735225a3a5528 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Wed, 8 Nov 2023 10:56:32 +0700 Subject: [PATCH 074/113] chore: generate reqs file from up-to-date deps Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- .../requirements/py3.10-ci-requirements.txt | 327 +++++++---------- .../requirements/py3.10-requirements.txt | 65 ++-- .../requirements/py3.8-ci-requirements.txt | 319 +++++++---------- .../requirements/py3.8-requirements.txt | 61 ++-- .../requirements/py3.9-ci-requirements.txt | 329 +++++++----------- .../requirements/py3.9-requirements.txt | 65 ++-- 6 files changed, 468 insertions(+), 698 deletions(-) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index 616ec5a2288..c74a3f12e15 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -4,93 +4,64 @@ # # pip-compile --extra=ci --output-file=sdk/python/requirements/py3.10-ci-requirements.txt # -adal==1.2.7 - # via msrestazure -adlfs==0.5.9 - # via feast (setup.py) -aiohttp==3.8.5 - # via - # adlfs - # gcsfs -aiosignal==1.3.1 - # via aiohttp alabaster==0.7.13 # via sphinx altair==4.2.0 # via great-expectations anyio==4.0.0 # via - # httpcore + # httpx # jupyter-server # starlette # watchfiles appdirs==1.4.4 # via fissix -appnope==0.1.3 - # via - # ipykernel - # ipython argon2-cffi==23.1.0 # via jupyter-server argon2-cffi-bindings==21.2.0 # via argon2-cffi -arrow==1.2.3 +arrow==1.3.0 # via isoduration asn1crypto==1.5.1 - # via - # oscrypto - # snowflake-connector-python + # via snowflake-connector-python assertpy==1.1 # via feast (setup.py) -asttokens==2.4.0 +asttokens==2.4.1 # via stack-data async-lru==2.0.4 # via jupyterlab async-timeout==4.0.3 - # via - # aiohttp - # redis + # via redis attrs==23.1.0 # via - # aiohttp # bowler # jsonschema # referencing -avro==1.11.3 +avro==1.10.0 # via feast (setup.py) -azure-core==1.29.4 +azure-core==1.29.5 # via - # adlfs # azure-identity # azure-storage-blob - # msrest -azure-datalake-store==0.0.53 - # via adlfs -azure-identity==1.14.0 - # via - # adlfs - # feast (setup.py) -azure-storage-blob==12.17.0 - # via - # adlfs - # feast (setup.py) -babel==2.12.1 +azure-identity==1.15.0 + # via feast (setup.py) +azure-storage-blob==12.19.0 + # via feast (setup.py) +babel==2.13.1 # via # jupyterlab-server # sphinx -backcall==0.2.0 - # via ipython beautifulsoup4==4.12.2 # via nbconvert black==22.12.0 # via feast (setup.py) -bleach==6.0.0 +bleach==6.1.0 # via nbconvert -boto3==1.28.43 +boto3==1.28.80 # via # feast (setup.py) # moto -botocore==1.31.43 +botocore==1.31.80 # via # boto3 # moto @@ -105,7 +76,7 @@ bytewax==0.15.1 # via feast (setup.py) cachecontrol==0.13.1 # via firebase-admin -cachetools==5.3.1 +cachetools==5.3.2 # via google-auth cassandra-driver==3.28.0 # via feast (setup.py) @@ -115,20 +86,17 @@ certifi==2023.7.22 # httpx # kubernetes # minio - # msrest # requests # snowflake-connector-python -cffi==1.15.1 +cffi==1.16.0 # via # argon2-cffi-bindings - # azure-datalake-store # cryptography # snowflake-connector-python cfgv==3.4.0 # via pre-commit -charset-normalizer==3.2.0 +charset-normalizer==3.3.2 # via - # aiohttp # requests # snowflake-connector-python click==8.1.7 @@ -142,21 +110,20 @@ click==8.1.7 # moreorless # pip-tools # uvicorn -cloudpickle==2.2.1 +cloudpickle==3.0.0 # via dask colorama==0.4.6 # via # feast (setup.py) # great-expectations -comm==0.1.4 +comm==0.2.0 # via # ipykernel # ipywidgets -coverage[toml]==7.3.1 +coverage[toml]==7.3.2 # via pytest-cov -cryptography==41.0.4 +cryptography==41.0.5 # via - # adal # azure-identity # azure-storage-blob # feast (setup.py) @@ -168,16 +135,14 @@ cryptography==41.0.4 # snowflake-connector-python # types-pyopenssl # types-redis -dask==2023.9.1 +dask==2023.10.1 # via feast (setup.py) db-dtypes==1.1.1 # via google-cloud-bigquery -debugpy==1.7.0 +debugpy==1.8.0 # via ipykernel decorator==5.1.1 - # via - # gcsfs - # ipython + # via ipython defusedxml==0.7.1 # via nbconvert deprecation==2.1.0 @@ -204,17 +169,17 @@ exceptiongroup==1.1.3 # pytest execnet==2.0.2 # via pytest-xdist -executing==1.2.0 +executing==2.0.1 # via stack-data fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.3 +fastavro==1.9.0 # via # feast (setup.py) # pandavro -fastjsonschema==2.18.0 +fastjsonschema==2.18.1 # via nbformat -filelock==3.12.3 +filelock==3.13.1 # via # snowflake-connector-python # virtualenv @@ -226,22 +191,15 @@ flake8==6.0.0 # via feast (setup.py) fqdn==1.5.1 # via jsonschema -frozenlist==1.4.0 +fsspec==2023.9.2 # via - # aiohttp - # aiosignal -fsspec==2022.1.0 - # via - # adlfs # dask - # gcsfs -gcsfs==2022.1.0 - # via feast (setup.py) + # feast (setup.py) geojson==2.5.0 # via rockset geomet==0.2.1.post1 # via cassandra-driver -google-api-core[grpc]==2.11.1 +google-api-core[grpc]==2.13.0 # via # feast (setup.py) # firebase-admin @@ -253,23 +211,19 @@ google-api-core[grpc]==2.11.1 # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.98.0 +google-api-python-client==2.107.0 # via firebase-admin -google-auth==2.22.0 +google-auth==2.23.4 # via - # gcsfs # google-api-core # google-api-python-client # google-auth-httplib2 - # google-auth-oauthlib # google-cloud-core # google-cloud-storage # kubernetes -google-auth-httplib2==0.1.0 +google-auth-httplib2==0.1.1 # via google-api-python-client -google-auth-oauthlib==1.0.0 - # via gcsfs -google-cloud-bigquery[pandas]==3.11.4 +google-cloud-bigquery[pandas]==3.12.0 # via feast (setup.py) google-cloud-bigquery-storage==2.22.0 # via feast (setup.py) @@ -284,20 +238,21 @@ google-cloud-core==2.3.3 # google-cloud-storage google-cloud-datastore==2.18.0 # via feast (setup.py) -google-cloud-firestore==2.11.1 +google-cloud-firestore==2.13.1 # via firebase-admin -google-cloud-storage==2.10.0 +google-cloud-storage==2.13.0 # via # feast (setup.py) # firebase-admin - # gcsfs google-crc32c==1.5.0 - # via google-resumable-media + # via + # google-cloud-storage + # google-resumable-media google-resumable-media==2.6.0 # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.60.0 +googleapis-common-protos[grpc]==1.61.0 # via # feast (setup.py) # google-api-core @@ -305,9 +260,11 @@ googleapis-common-protos[grpc]==1.60.0 # grpcio-status great-expectations==0.15.50 # via feast (setup.py) +greenlet==3.0.1 + # via sqlalchemy grpc-google-iam-v1==0.12.6 # via google-cloud-bigtable -grpcio==1.58.0 +grpcio==1.59.2 # via # feast (setup.py) # google-api-core @@ -319,15 +276,15 @@ grpcio==1.58.0 # grpcio-status # grpcio-testing # grpcio-tools -grpcio-health-checking==1.58.0 +grpcio-health-checking==1.59.2 # via feast (setup.py) -grpcio-reflection==1.58.0 +grpcio-reflection==1.59.2 # via feast (setup.py) -grpcio-status==1.58.0 +grpcio-status==1.59.2 # via google-api-core -grpcio-testing==1.58.0 +grpcio-testing==1.59.2 # via feast (setup.py) -grpcio-tools==1.58.0 +grpcio-tools==1.59.2 # via feast (setup.py) gunicorn==21.2.0 # via feast (setup.py) @@ -341,17 +298,17 @@ hazelcast-python-client==5.3.0 # via feast (setup.py) hiredis==2.2.3 # via feast (setup.py) -httpcore==0.17.3 +httpcore==1.0.1 # via httpx httplib2==0.22.0 # via # google-api-python-client # google-auth-httplib2 -httptools==0.6.0 +httptools==0.6.1 # via uvicorn -httpx==0.24.1 +httpx==0.25.1 # via feast (setup.py) -identify==2.5.27 +identify==2.5.31 # via pre-commit idna==3.4 # via @@ -360,7 +317,6 @@ idna==3.4 # jsonschema # requests # snowflake-connector-python - # yarl imagesize==1.4.1 # via sphinx importlib-metadata==6.8.0 @@ -368,28 +324,26 @@ importlib-metadata==6.8.0 # dask # feast (setup.py) # great-expectations -importlib-resources==6.0.1 +importlib-resources==6.1.1 # via feast (setup.py) iniconfig==2.0.0 # via pytest -ipykernel==6.25.2 +ipykernel==6.26.0 # via jupyterlab -ipython==8.15.0 +ipython==8.17.2 # via # great-expectations # ipykernel # ipywidgets -ipywidgets==8.1.0 +ipywidgets==8.1.1 # via great-expectations isodate==0.6.1 - # via - # azure-storage-blob - # msrest + # via azure-storage-blob isoduration==20.11.0 # via jsonschema isort==5.12.0 # via feast (setup.py) -jedi==0.19.0 +jedi==0.19.1 # via ipython jinja2==3.1.2 # via @@ -414,7 +368,7 @@ jsonpointer==2.4 # via # jsonpatch # jsonschema -jsonschema[format-nongpl]==4.19.0 +jsonschema[format-nongpl]==4.19.2 # via # altair # feast (setup.py) @@ -424,12 +378,12 @@ jsonschema[format-nongpl]==4.19.0 # nbformat jsonschema-specifications==2023.7.1 # via jsonschema -jupyter-client==8.3.1 +jupyter-client==8.6.0 # via # ipykernel # jupyter-server # nbclient -jupyter-core==5.3.1 +jupyter-core==5.5.0 # via # ipykernel # jupyter-client @@ -438,11 +392,11 @@ jupyter-core==5.3.1 # nbclient # nbconvert # nbformat -jupyter-events==0.7.0 +jupyter-events==0.9.0 # via jupyter-server jupyter-lsp==2.2.0 # via jupyterlab -jupyter-server==2.7.3 +jupyter-server==2.10.0 # via # jupyter-lsp # jupyterlab @@ -451,15 +405,15 @@ jupyter-server==2.7.3 # notebook-shim jupyter-server-terminals==0.4.4 # via jupyter-server -jupyterlab==4.0.5 +jupyterlab==4.0.8 # via notebook jupyterlab-pygments==0.2.2 # via nbconvert -jupyterlab-server==2.24.0 +jupyterlab-server==2.25.0 # via # jupyterlab # notebook -jupyterlab-widgets==3.0.8 +jupyterlab-widgets==3.0.9 # via ipywidgets kubernetes==20.13.0 # via feast (setup.py) @@ -482,7 +436,7 @@ mccabe==0.7.0 # via flake8 minio==7.1.0 # via feast (setup.py) -mistune==3.0.1 +mistune==3.0.2 # via # great-expectations # nbconvert @@ -492,25 +446,16 @@ mock==2.0.0 # via feast (setup.py) moreorless==0.4.0 # via bowler -moto==4.2.2 +moto==4.2.7 # via feast (setup.py) -msal==1.23.0 +msal==1.25.0 # via - # azure-datalake-store # azure-identity # msal-extensions msal-extensions==1.0.0 # via azure-identity -msgpack==1.0.5 +msgpack==1.0.7 # via cachecontrol -msrest==0.7.1 - # via msrestazure -msrestazure==0.6.4 - # via adlfs -multidict==6.0.4 - # via - # aiohttp - # yarl multiprocess==0.70.15 # via bytewax mypy==0.982 @@ -521,13 +466,13 @@ mypy-extensions==1.0.0 # via # black # mypy -mypy-protobuf==3.1 +mypy-protobuf==3.1.0 # via feast (setup.py) mysqlclient==2.2.0 # via feast (setup.py) -nbclient==0.8.0 +nbclient==0.9.0 # via nbconvert -nbconvert==7.8.0 +nbconvert==7.11.0 # via jupyter-server nbformat==5.9.2 # via @@ -535,11 +480,11 @@ nbformat==5.9.2 # jupyter-server # nbclient # nbconvert -nest-asyncio==1.5.7 +nest-asyncio==1.5.8 # via ipykernel nodeenv==1.8.0 # via pre-commit -notebook==7.0.3 +notebook==7.0.6 # via great-expectations notebook-shim==0.2.3 # via @@ -557,11 +502,9 @@ numpy==1.24.4 # scipy oauthlib==3.2.2 # via requests-oauthlib -oscrypto==1.3.0 - # via snowflake-connector-python overrides==7.4.0 # via jupyter-server -packaging==23.1 +packaging==23.2 # via # build # dask @@ -595,19 +538,17 @@ pandocfilters==1.5.0 # via nbconvert parso==0.8.3 # via jedi -partd==1.4.0 +partd==1.4.1 # via dask pathspec==0.11.2 # via black -pbr==5.11.1 +pbr==6.0.0 # via mock pexpect==4.8.0 # via ipython -pickleshare==0.7.5 - # via ipython pip-tools==7.3.0 # via feast (setup.py) -platformdirs==3.8.1 +platformdirs==3.11.0 # via # black # jupyter-core @@ -617,11 +558,11 @@ pluggy==1.3.0 # via pytest ply==3.11 # via thriftpy2 -portalocker==2.7.0 +portalocker==2.8.2 # via msal-extensions pre-commit==3.3.1 # via feast (setup.py) -prometheus-client==0.17.1 +prometheus-client==0.18.0 # via jupyter-server prompt-toolkit==3.0.39 # via ipython @@ -655,7 +596,7 @@ psutil==5.9.0 # via # feast (setup.py) # ipykernel -psycopg2-binary==2.9.7 +psycopg2-binary==2.9.9 # via feast (setup.py) ptyprocess==0.7.0 # via @@ -687,9 +628,7 @@ pycodestyle==2.10.0 # via flake8 pycparser==2.21 # via cffi -pycryptodomex==3.18.0 - # via snowflake-connector-python -pydantic==1.10.12 +pydantic==1.10.13 # via # fastapi # feast (setup.py) @@ -704,16 +643,15 @@ pygments==2.16.1 # sphinx pyjwt[crypto]==2.8.0 # via - # adal # msal # snowflake-connector-python -pymssql==2.2.8 +pymssql==2.2.10 # via feast (setup.py) pymysql==1.1.0 # via feast (setup.py) -pyodbc==4.0.39 +pyodbc==5.0.1 # via feast (setup.py) -pyopenssl==23.2.0 +pyopenssl==23.3.0 # via snowflake-connector-python pyparsing==3.1.1 # via @@ -721,9 +659,9 @@ pyparsing==3.1.1 # httplib2 pyproject-hooks==1.0.0 # via build -pyspark==3.4.1 +pyspark==3.5.0 # via feast (setup.py) -pytest==7.4.2 +pytest==7.4.3 # via # feast (setup.py) # pytest-benchmark @@ -749,7 +687,6 @@ pytest-xdist==3.3.1 # via feast (setup.py) python-dateutil==2.8.2 # via - # adal # arrow # botocore # google-cloud-bigquery @@ -791,18 +728,14 @@ referencing==0.30.2 # jsonschema # jsonschema-specifications # jupyter-events -regex==2023.8.8 +regex==2023.10.3 # via feast (setup.py) requests==2.31.0 # via - # adal - # adlfs # azure-core - # azure-datalake-store # cachecontrol # docker # feast (setup.py) - # gcsfs # google-api-core # google-cloud-bigquery # google-cloud-storage @@ -811,18 +744,14 @@ requests==2.31.0 # kubernetes # moto # msal - # msrest # requests-oauthlib # responses # snowflake-connector-python # sphinx # trino requests-oauthlib==1.3.1 - # via - # google-auth-oauthlib - # kubernetes - # msrest -responses==0.23.3 + # via kubernetes +responses==0.24.0 # via moto rfc3339-validator==0.1.4 # via @@ -834,7 +763,7 @@ rfc3986-validator==0.1.1 # jupyter-events rockset==2.1.0 # via feast (setup.py) -rpds-py==0.10.2 +rpds-py==0.12.0 # via # jsonschema # referencing @@ -842,9 +771,9 @@ rsa==4.9 # via google-auth ruamel-yaml==0.17.17 # via great-expectations -s3transfer==0.6.2 +s3transfer==0.7.0 # via boto3 -scipy==1.11.2 +scipy==1.11.3 # via great-expectations send2trash==1.8.2 # via jupyter-server @@ -855,13 +784,10 @@ six==1.16.0 # bleach # cassandra-driver # geomet - # google-auth - # google-auth-httplib2 # happybase # isodate # kubernetes # mock - # msrestazure # pandavro # python-dateutil # rfc3339-validator @@ -869,11 +795,10 @@ six==1.16.0 sniffio==1.3.0 # via # anyio - # httpcore # httpx snowballstemmer==2.2.0 # via sphinx -snowflake-connector-python[pandas]==3.1.1 +snowflake-connector-python[pandas]==3.4.0 # via feast (setup.py) sortedcontainers==2.4.0 # via snowflake-connector-python @@ -899,11 +824,11 @@ sphinxcontrib-qthelp==1.0.6 # via sphinx sphinxcontrib-serializinghtml==1.1.9 # via sphinx -sqlalchemy[mypy]==1.4.49 +sqlalchemy[mypy]==1.4.50 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a35 +sqlalchemy2-stubs==0.0.2a36 # via sqlalchemy -stack-data==0.6.2 +stack-data==0.6.3 # via ipython starlette==0.27.0 # via fastapi @@ -917,7 +842,7 @@ terminado==0.17.1 # jupyter-server-terminals testcontainers==3.7.1 # via feast (setup.py) -thriftpy2==0.4.16 +thriftpy2==0.4.17 # via happybase tinycss2==1.2.1 # via nbconvert @@ -933,7 +858,7 @@ tomli==2.0.1 # pip-tools # pyproject-hooks # pytest -tomlkit==0.12.1 +tomlkit==0.12.2 # via snowflake-connector-python toolz==0.12.0 # via @@ -952,7 +877,7 @@ tqdm==4.66.1 # via # feast (setup.py) # great-expectations -traitlets==5.9.0 +traitlets==5.13.0 # via # comm # ipykernel @@ -967,7 +892,7 @@ traitlets==5.9.0 # nbclient # nbconvert # nbformat -trino==0.326.0 +trino==0.327.0 # via feast (setup.py) typeguard==2.13.3 # via feast (setup.py) @@ -977,19 +902,19 @@ types-protobuf==3.19.22 # mypy-protobuf types-pymysql==1.1.0.1 # via feast (setup.py) -types-pyopenssl==23.2.0.2 +types-pyopenssl==23.3.0.0 # via types-redis types-python-dateutil==2.8.19.14 - # via feast (setup.py) -types-pytz==2023.3.0.1 - # via feast (setup.py) -types-pyyaml==6.0.12.11 # via + # arrow # feast (setup.py) - # responses -types-redis==4.6.0.5 +types-pytz==2023.3.1.1 + # via feast (setup.py) +types-pyyaml==6.0.12.12 + # via feast (setup.py) +types-redis==4.6.0.10 # via feast (setup.py) -types-requests==2.31.0.2 +types-requests==2.30.0.0 # via feast (setup.py) types-setuptools==68.2.0.0 # via feast (setup.py) @@ -997,20 +922,19 @@ types-tabulate==0.9.0.3 # via feast (setup.py) types-urllib3==1.26.25.14 # via types-requests -typing-extensions==4.7.1 +typing-extensions==4.8.0 # via # async-lru # azure-core # azure-storage-blob # fastapi - # filelock # great-expectations # mypy # pydantic # snowflake-connector-python # sqlalchemy2-stubs # uvicorn -tzlocal==5.0.1 +tzlocal==5.2 # via # great-expectations # trino @@ -1023,7 +947,6 @@ urllib3==1.26.18 # botocore # docker # feast (setup.py) - # google-auth # great-expectations # kubernetes # minio @@ -1031,9 +954,9 @@ urllib3==1.26.18 # responses # rockset # snowflake-connector-python -uvicorn[standard]==0.23.2 +uvicorn[standard]==0.24.0.post1 # via feast (setup.py) -uvloop==0.17.0 +uvloop==0.19.0 # via uvicorn virtualenv==20.23.0 # via @@ -1041,9 +964,9 @@ virtualenv==20.23.0 # pre-commit volatile==2.1.0 # via bowler -watchfiles==0.20.0 +watchfiles==0.21.0 # via uvicorn -wcwidth==0.2.6 +wcwidth==0.2.9 # via prompt-toolkit webcolors==1.13 # via jsonschema @@ -1051,26 +974,24 @@ webencodings==0.5.1 # via # bleach # tinycss2 -websocket-client==1.6.2 +websocket-client==1.6.4 # via # docker # jupyter-server # kubernetes -websockets==11.0.3 +websockets==12.0 # via uvicorn -werkzeug==2.3.7 +werkzeug==3.0.1 # via moto -wheel==0.41.2 +wheel==0.41.3 # via pip-tools -widgetsnbextension==4.0.8 +widgetsnbextension==4.0.9 # via ipywidgets wrapt==1.15.0 # via testcontainers xmltodict==0.13.0 # via moto -yarl==1.9.2 - # via aiohttp -zipp==3.16.2 +zipp==3.17.0 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: diff --git a/sdk/python/requirements/py3.10-requirements.txt b/sdk/python/requirements/py3.10-requirements.txt index f4cac316d22..41fee168bf4 100644 --- a/sdk/python/requirements/py3.10-requirements.txt +++ b/sdk/python/requirements/py3.10-requirements.txt @@ -6,7 +6,7 @@ # anyio==4.0.0 # via - # httpcore + # httpx # starlette # watchfiles appdirs==1.4.4 @@ -23,7 +23,7 @@ certifi==2023.7.22 # httpcore # httpx # requests -charset-normalizer==3.2.0 +charset-normalizer==3.3.2 # via requests click==8.1.7 # via @@ -32,11 +32,11 @@ click==8.1.7 # feast (setup.py) # moreorless # uvicorn -cloudpickle==2.2.1 +cloudpickle==3.0.0 # via dask colorama==0.4.6 # via feast (setup.py) -dask==2023.9.1 +dask==2023.10.1 # via feast (setup.py) dill==0.3.7 # via feast (setup.py) @@ -44,25 +44,27 @@ exceptiongroup==1.1.3 # via anyio fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.3 +fastavro==1.9.0 # via # feast (setup.py) # pandavro fissix==21.11.13 # via bowler -fsspec==2023.9.0 +fsspec==2023.10.0 # via dask -grpcio==1.58.0 +greenlet==3.0.1 + # via sqlalchemy +grpcio==1.59.2 # via # feast (setup.py) # grpcio-health-checking # grpcio-reflection # grpcio-tools -grpcio-health-checking==1.58.0 +grpcio-health-checking==1.59.2 # via feast (setup.py) -grpcio-reflection==1.58.0 +grpcio-reflection==1.59.2 # via feast (setup.py) -grpcio-tools==1.58.0 +grpcio-tools==1.59.2 # via feast (setup.py) gunicorn==21.2.0 # via feast (setup.py) @@ -70,11 +72,11 @@ h11==0.14.0 # via # httpcore # uvicorn -httpcore==0.17.3 +httpcore==1.0.1 # via httpx -httptools==0.6.0 +httptools==0.6.1 # via uvicorn -httpx==0.24.1 +httpx==0.25.1 # via feast (setup.py) idna==3.4 # via @@ -85,11 +87,11 @@ importlib-metadata==6.8.0 # via # dask # feast (setup.py) -importlib-resources==6.0.1 +importlib-resources==6.1.1 # via feast (setup.py) jinja2==3.1.2 # via feast (setup.py) -jsonschema==4.19.0 +jsonschema==4.19.2 # via feast (setup.py) jsonschema-specifications==2023.7.1 # via jsonschema @@ -101,11 +103,11 @@ mmh3==4.0.1 # via feast (setup.py) moreorless==0.4.0 # via bowler -mypy==1.5.1 +mypy==1.6.1 # via sqlalchemy mypy-extensions==1.0.0 # via mypy -mypy-protobuf==3.1 +mypy-protobuf==3.1.0 # via feast (setup.py) numpy==1.24.4 # via @@ -113,7 +115,7 @@ numpy==1.24.4 # pandas # pandavro # pyarrow -packaging==23.1 +packaging==23.2 # via # dask # gunicorn @@ -123,7 +125,7 @@ pandas==1.5.3 # pandavro pandavro==1.5.2 # via feast (setup.py) -partd==1.4.0 +partd==1.4.1 # via dask proto-plus==1.22.3 # via feast (setup.py) @@ -137,7 +139,7 @@ protobuf==4.23.3 # proto-plus pyarrow==11.0.0 # via feast (setup.py) -pydantic==1.10.12 +pydantic==1.10.13 # via # fastapi # feast (setup.py) @@ -160,7 +162,7 @@ referencing==0.30.2 # jsonschema-specifications requests==2.31.0 # via feast (setup.py) -rpds-py==0.10.2 +rpds-py==0.12.0 # via # jsonschema # referencing @@ -171,11 +173,10 @@ six==1.16.0 sniffio==1.3.0 # via # anyio - # httpcore # httpx -sqlalchemy[mypy]==1.4.49 +sqlalchemy[mypy]==1.4.50 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a35 +sqlalchemy2-stubs==0.0.2a36 # via sqlalchemy starlette==0.27.0 # via fastapi @@ -195,28 +196,28 @@ tqdm==4.66.1 # via feast (setup.py) typeguard==2.13.3 # via feast (setup.py) -types-protobuf==4.24.0.1 +types-protobuf==4.24.0.4 # via mypy-protobuf -typing-extensions==4.7.1 +typing-extensions==4.8.0 # via # fastapi # mypy # pydantic # sqlalchemy2-stubs # uvicorn -urllib3==1.26.18 +urllib3==2.0.7 # via requests -uvicorn[standard]==0.23.2 +uvicorn[standard]==0.24.0.post1 # via feast (setup.py) -uvloop==0.17.0 +uvloop==0.19.0 # via uvicorn volatile==2.1.0 # via bowler -watchfiles==0.20.0 +watchfiles==0.21.0 # via uvicorn -websockets==11.0.3 +websockets==12.0 # via uvicorn -zipp==3.16.2 +zipp==3.17.0 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index b84305d92f3..855074057a9 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -4,77 +4,50 @@ # # pip-compile --extra=ci --output-file=sdk/python/requirements/py3.8-ci-requirements.txt # -adal==1.2.7 - # via msrestazure -adlfs==0.5.9 - # via feast (setup.py) -aiohttp==3.8.5 - # via - # adlfs - # gcsfs -aiosignal==1.3.1 - # via aiohttp alabaster==0.7.13 # via sphinx altair==4.2.0 # via great-expectations anyio==4.0.0 # via - # httpcore + # httpx # jupyter-server # starlette # watchfiles appdirs==1.4.4 # via fissix -appnope==0.1.3 - # via - # ipykernel - # ipython argon2-cffi==23.1.0 # via jupyter-server argon2-cffi-bindings==21.2.0 # via argon2-cffi -arrow==1.2.3 +arrow==1.3.0 # via isoduration asn1crypto==1.5.1 - # via - # oscrypto - # snowflake-connector-python + # via snowflake-connector-python assertpy==1.1 # via feast (setup.py) -asttokens==2.4.0 +asttokens==2.4.1 # via stack-data async-lru==2.0.4 # via jupyterlab async-timeout==4.0.3 - # via - # aiohttp - # redis + # via redis attrs==23.1.0 # via - # aiohttp # bowler # jsonschema # referencing -avro==1.11.3 +avro==1.10.0 # via feast (setup.py) -azure-core==1.29.3 +azure-core==1.29.5 # via - # adlfs # azure-identity # azure-storage-blob - # msrest -azure-datalake-store==0.0.53 - # via adlfs -azure-identity==1.14.0 - # via - # adlfs - # feast (setup.py) -azure-storage-blob==12.17.0 - # via - # adlfs - # feast (setup.py) -babel==2.12.1 +azure-identity==1.15.0 + # via feast (setup.py) +azure-storage-blob==12.19.0 + # via feast (setup.py) +babel==2.13.1 # via # jupyterlab-server # sphinx @@ -88,13 +61,13 @@ beautifulsoup4==4.12.2 # via nbconvert black==22.12.0 # via feast (setup.py) -bleach==6.0.0 +bleach==6.1.0 # via nbconvert -boto3==1.28.42 +boto3==1.28.80 # via # feast (setup.py) # moto -botocore==1.31.42 +botocore==1.31.80 # via # boto3 # moto @@ -109,7 +82,7 @@ bytewax==0.15.1 # via feast (setup.py) cachecontrol==0.13.1 # via firebase-admin -cachetools==5.3.1 +cachetools==5.3.2 # via google-auth cassandra-driver==3.28.0 # via feast (setup.py) @@ -119,20 +92,17 @@ certifi==2023.7.22 # httpx # kubernetes # minio - # msrest # requests # snowflake-connector-python -cffi==1.15.1 +cffi==1.16.0 # via # argon2-cffi-bindings - # azure-datalake-store # cryptography # snowflake-connector-python cfgv==3.4.0 # via pre-commit -charset-normalizer==3.2.0 +charset-normalizer==3.3.2 # via - # aiohttp # requests # snowflake-connector-python click==8.1.7 @@ -146,21 +116,20 @@ click==8.1.7 # moreorless # pip-tools # uvicorn -cloudpickle==2.2.1 +cloudpickle==3.0.0 # via dask colorama==0.4.6 # via # feast (setup.py) # great-expectations -comm==0.1.4 +comm==0.2.0 # via # ipykernel # ipywidgets -coverage[toml]==7.3.1 +coverage[toml]==7.3.2 # via pytest-cov -cryptography==41.0.4 +cryptography==41.0.5 # via - # adal # azure-identity # azure-storage-blob # feast (setup.py) @@ -176,12 +145,10 @@ dask==2023.5.0 # via feast (setup.py) db-dtypes==1.1.1 # via google-cloud-bigquery -debugpy==1.6.7.post1 +debugpy==1.8.0 # via ipykernel decorator==5.1.1 - # via - # gcsfs - # ipython + # via ipython defusedxml==0.7.1 # via nbconvert deprecation==2.1.0 @@ -207,17 +174,17 @@ exceptiongroup==1.1.3 # pytest execnet==2.0.2 # via pytest-xdist -executing==1.2.0 +executing==2.0.1 # via stack-data fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.2 +fastavro==1.9.0 # via # feast (setup.py) # pandavro -fastjsonschema==2.18.0 +fastjsonschema==2.18.1 # via nbformat -filelock==3.12.3 +filelock==3.13.1 # via # snowflake-connector-python # virtualenv @@ -229,22 +196,15 @@ flake8==6.0.0 # via feast (setup.py) fqdn==1.5.1 # via jsonschema -frozenlist==1.4.0 +fsspec==2023.9.2 # via - # aiohttp - # aiosignal -fsspec==2022.1.0 - # via - # adlfs # dask - # gcsfs -gcsfs==2022.1.0 - # via feast (setup.py) + # feast (setup.py) geojson==2.5.0 # via rockset geomet==0.2.1.post1 # via cassandra-driver -google-api-core[grpc]==2.11.1 +google-api-core[grpc]==2.13.0 # via # feast (setup.py) # firebase-admin @@ -256,23 +216,19 @@ google-api-core[grpc]==2.11.1 # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.98.0 +google-api-python-client==2.107.0 # via firebase-admin -google-auth==2.22.0 +google-auth==2.23.4 # via - # gcsfs # google-api-core # google-api-python-client # google-auth-httplib2 - # google-auth-oauthlib # google-cloud-core # google-cloud-storage # kubernetes -google-auth-httplib2==0.1.0 +google-auth-httplib2==0.1.1 # via google-api-python-client -google-auth-oauthlib==1.0.0 - # via gcsfs -google-cloud-bigquery[pandas]==3.11.4 +google-cloud-bigquery[pandas]==3.12.0 # via feast (setup.py) google-cloud-bigquery-storage==2.22.0 # via feast (setup.py) @@ -287,20 +243,21 @@ google-cloud-core==2.3.3 # google-cloud-storage google-cloud-datastore==2.18.0 # via feast (setup.py) -google-cloud-firestore==2.11.1 +google-cloud-firestore==2.13.1 # via firebase-admin -google-cloud-storage==2.10.0 +google-cloud-storage==2.13.0 # via # feast (setup.py) # firebase-admin - # gcsfs google-crc32c==1.5.0 - # via google-resumable-media + # via + # google-cloud-storage + # google-resumable-media google-resumable-media==2.6.0 # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.60.0 +googleapis-common-protos[grpc]==1.61.0 # via # feast (setup.py) # google-api-core @@ -308,9 +265,11 @@ googleapis-common-protos[grpc]==1.60.0 # grpcio-status great-expectations==0.15.50 # via feast (setup.py) +greenlet==3.0.1 + # via sqlalchemy grpc-google-iam-v1==0.12.6 # via google-cloud-bigtable -grpcio==1.57.0 +grpcio==1.59.2 # via # feast (setup.py) # google-api-core @@ -322,15 +281,15 @@ grpcio==1.57.0 # grpcio-status # grpcio-testing # grpcio-tools -grpcio-health-checking==1.57.0 +grpcio-health-checking==1.59.2 # via feast (setup.py) -grpcio-reflection==1.57.0 +grpcio-reflection==1.59.2 # via feast (setup.py) -grpcio-status==1.57.0 +grpcio-status==1.59.2 # via google-api-core -grpcio-testing==1.57.0 +grpcio-testing==1.59.2 # via feast (setup.py) -grpcio-tools==1.57.0 +grpcio-tools==1.59.2 # via feast (setup.py) gunicorn==21.2.0 # via feast (setup.py) @@ -344,17 +303,17 @@ hazelcast-python-client==5.3.0 # via feast (setup.py) hiredis==2.2.3 # via feast (setup.py) -httpcore==0.17.3 +httpcore==1.0.1 # via httpx httplib2==0.22.0 # via # google-api-python-client # google-auth-httplib2 -httptools==0.6.0 +httptools==0.6.1 # via uvicorn -httpx==0.24.1 +httpx==0.25.1 # via feast (setup.py) -identify==2.5.27 +identify==2.5.31 # via pre-commit idna==3.4 # via @@ -363,7 +322,6 @@ idna==3.4 # jsonschema # requests # snowflake-connector-python - # yarl imagesize==1.4.1 # via sphinx importlib-metadata==6.8.0 @@ -378,7 +336,7 @@ importlib-metadata==6.8.0 # jupyterlab-server # nbconvert # sphinx -importlib-resources==6.0.1 +importlib-resources==6.1.1 # via # feast (setup.py) # jsonschema @@ -386,24 +344,22 @@ importlib-resources==6.0.1 # jupyterlab iniconfig==2.0.0 # via pytest -ipykernel==6.25.2 +ipykernel==6.26.0 # via jupyterlab -ipython==8.12.2 +ipython==8.12.3 # via # great-expectations # ipykernel # ipywidgets -ipywidgets==8.1.0 +ipywidgets==8.1.1 # via great-expectations isodate==0.6.1 - # via - # azure-storage-blob - # msrest + # via azure-storage-blob isoduration==20.11.0 # via jsonschema isort==5.12.0 # via feast (setup.py) -jedi==0.19.0 +jedi==0.19.1 # via ipython jinja2==3.1.2 # via @@ -428,7 +384,7 @@ jsonpointer==2.4 # via # jsonpatch # jsonschema -jsonschema[format-nongpl]==4.19.0 +jsonschema[format-nongpl]==4.19.2 # via # altair # feast (setup.py) @@ -438,12 +394,12 @@ jsonschema[format-nongpl]==4.19.0 # nbformat jsonschema-specifications==2023.7.1 # via jsonschema -jupyter-client==8.3.1 +jupyter-client==8.6.0 # via # ipykernel # jupyter-server # nbclient -jupyter-core==5.3.1 +jupyter-core==5.5.0 # via # ipykernel # jupyter-client @@ -452,11 +408,11 @@ jupyter-core==5.3.1 # nbclient # nbconvert # nbformat -jupyter-events==0.7.0 +jupyter-events==0.9.0 # via jupyter-server jupyter-lsp==2.2.0 # via jupyterlab -jupyter-server==2.7.3 +jupyter-server==2.10.0 # via # jupyter-lsp # jupyterlab @@ -465,15 +421,15 @@ jupyter-server==2.7.3 # notebook-shim jupyter-server-terminals==0.4.4 # via jupyter-server -jupyterlab==4.0.5 +jupyterlab==4.0.8 # via notebook jupyterlab-pygments==0.2.2 # via nbconvert -jupyterlab-server==2.24.0 +jupyterlab-server==2.25.0 # via # jupyterlab # notebook -jupyterlab-widgets==3.0.8 +jupyterlab-widgets==3.0.9 # via ipywidgets kubernetes==20.13.0 # via feast (setup.py) @@ -496,7 +452,7 @@ mccabe==0.7.0 # via flake8 minio==7.1.0 # via feast (setup.py) -mistune==3.0.1 +mistune==3.0.2 # via # great-expectations # nbconvert @@ -506,25 +462,16 @@ mock==2.0.0 # via feast (setup.py) moreorless==0.4.0 # via bowler -moto==4.2.2 +moto==4.2.7 # via feast (setup.py) -msal==1.23.0 +msal==1.25.0 # via - # azure-datalake-store # azure-identity # msal-extensions msal-extensions==1.0.0 # via azure-identity -msgpack==1.0.5 +msgpack==1.0.7 # via cachecontrol -msrest==0.7.1 - # via msrestazure -msrestazure==0.6.4 - # via adlfs -multidict==6.0.4 - # via - # aiohttp - # yarl multiprocess==0.70.15 # via bytewax mypy==0.982 @@ -539,9 +486,9 @@ mypy-protobuf==3.1.0 # via feast (setup.py) mysqlclient==2.2.0 # via feast (setup.py) -nbclient==0.8.0 +nbclient==0.9.0 # via nbconvert -nbconvert==7.8.0 +nbconvert==7.11.0 # via jupyter-server nbformat==5.9.2 # via @@ -549,11 +496,11 @@ nbformat==5.9.2 # jupyter-server # nbclient # nbconvert -nest-asyncio==1.5.7 +nest-asyncio==1.5.8 # via ipykernel nodeenv==1.8.0 # via pre-commit -notebook==7.0.3 +notebook==7.0.6 # via great-expectations notebook-shim==0.2.3 # via @@ -571,11 +518,9 @@ numpy==1.24.4 # scipy oauthlib==3.2.2 # via requests-oauthlib -oscrypto==1.3.0 - # via snowflake-connector-python overrides==7.4.0 # via jupyter-server -packaging==23.1 +packaging==23.2 # via # build # dask @@ -609,11 +554,11 @@ pandocfilters==1.5.0 # via nbconvert parso==0.8.3 # via jedi -partd==1.4.0 +partd==1.4.1 # via dask pathspec==0.11.2 # via black -pbr==5.11.1 +pbr==6.0.0 # via mock pexpect==4.8.0 # via ipython @@ -623,7 +568,7 @@ pip-tools==7.3.0 # via feast (setup.py) pkgutil-resolve-name==1.3.10 # via jsonschema -platformdirs==3.8.1 +platformdirs==3.11.0 # via # black # jupyter-core @@ -633,11 +578,11 @@ pluggy==1.3.0 # via pytest ply==3.11 # via thriftpy2 -portalocker==2.7.0 +portalocker==2.8.2 # via msal-extensions pre-commit==3.3.1 # via feast (setup.py) -prometheus-client==0.17.1 +prometheus-client==0.18.0 # via jupyter-server prompt-toolkit==3.0.39 # via ipython @@ -671,7 +616,7 @@ psutil==5.9.0 # via # feast (setup.py) # ipykernel -psycopg2-binary==2.9.7 +psycopg2-binary==2.9.9 # via feast (setup.py) ptyprocess==0.7.0 # via @@ -703,9 +648,7 @@ pycodestyle==2.10.0 # via flake8 pycparser==2.21 # via cffi -pycryptodomex==3.18.0 - # via snowflake-connector-python -pydantic==1.10.12 +pydantic==1.10.13 # via # fastapi # feast (setup.py) @@ -720,16 +663,15 @@ pygments==2.16.1 # sphinx pyjwt[crypto]==2.8.0 # via - # adal # msal # snowflake-connector-python -pymssql==2.2.8 +pymssql==2.2.10 # via feast (setup.py) pymysql==1.1.0 # via feast (setup.py) -pyodbc==4.0.39 +pyodbc==5.0.1 # via feast (setup.py) -pyopenssl==23.2.0 +pyopenssl==23.3.0 # via snowflake-connector-python pyparsing==3.1.1 # via @@ -737,9 +679,9 @@ pyparsing==3.1.1 # httplib2 pyproject-hooks==1.0.0 # via build -pyspark==3.4.1 +pyspark==3.5.0 # via feast (setup.py) -pytest==7.4.1 +pytest==7.4.3 # via # feast (setup.py) # pytest-benchmark @@ -765,7 +707,6 @@ pytest-xdist==3.3.1 # via feast (setup.py) python-dateutil==2.8.2 # via - # adal # arrow # botocore # google-cloud-bigquery @@ -808,18 +749,14 @@ referencing==0.30.2 # jsonschema # jsonschema-specifications # jupyter-events -regex==2023.8.8 +regex==2023.10.3 # via feast (setup.py) requests==2.31.0 # via - # adal - # adlfs # azure-core - # azure-datalake-store # cachecontrol # docker # feast (setup.py) - # gcsfs # google-api-core # google-cloud-bigquery # google-cloud-storage @@ -828,18 +765,14 @@ requests==2.31.0 # kubernetes # moto # msal - # msrest # requests-oauthlib # responses # snowflake-connector-python # sphinx # trino requests-oauthlib==1.3.1 - # via - # google-auth-oauthlib - # kubernetes - # msrest -responses==0.23.3 + # via kubernetes +responses==0.24.0 # via moto rfc3339-validator==0.1.4 # via @@ -851,7 +784,7 @@ rfc3986-validator==0.1.1 # jupyter-events rockset==2.1.0 # via feast (setup.py) -rpds-py==0.10.2 +rpds-py==0.12.0 # via # jsonschema # referencing @@ -859,9 +792,9 @@ rsa==4.9 # via google-auth ruamel-yaml==0.17.17 # via great-expectations -ruamel-yaml-clib==0.2.7 +ruamel-yaml-clib==0.2.8 # via ruamel-yaml -s3transfer==0.6.2 +s3transfer==0.7.0 # via boto3 scipy==1.10.1 # via great-expectations @@ -874,13 +807,10 @@ six==1.16.0 # bleach # cassandra-driver # geomet - # google-auth - # google-auth-httplib2 # happybase # isodate # kubernetes # mock - # msrestazure # pandavro # python-dateutil # rfc3339-validator @@ -888,11 +818,10 @@ six==1.16.0 sniffio==1.3.0 # via # anyio - # httpcore # httpx snowballstemmer==2.2.0 # via sphinx -snowflake-connector-python[pandas]==3.1.1 +snowflake-connector-python[pandas]==3.4.0 # via feast (setup.py) sortedcontainers==2.4.0 # via snowflake-connector-python @@ -912,11 +841,11 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx -sqlalchemy[mypy]==1.4.49 +sqlalchemy[mypy]==1.4.50 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a35 +sqlalchemy2-stubs==0.0.2a36 # via sqlalchemy -stack-data==0.6.2 +stack-data==0.6.3 # via ipython starlette==0.27.0 # via fastapi @@ -930,7 +859,7 @@ terminado==0.17.1 # jupyter-server-terminals testcontainers==3.7.1 # via feast (setup.py) -thriftpy2==0.4.16 +thriftpy2==0.4.17 # via happybase tinycss2==1.2.1 # via nbconvert @@ -946,7 +875,7 @@ tomli==2.0.1 # pip-tools # pyproject-hooks # pytest -tomlkit==0.12.1 +tomlkit==0.12.2 # via snowflake-connector-python toolz==0.12.0 # via @@ -965,7 +894,7 @@ tqdm==4.66.1 # via # feast (setup.py) # great-expectations -traitlets==5.9.0 +traitlets==5.13.0 # via # comm # ipykernel @@ -980,7 +909,7 @@ traitlets==5.9.0 # nbclient # nbconvert # nbformat -trino==0.326.0 +trino==0.327.0 # via feast (setup.py) typeguard==2.13.3 # via feast (setup.py) @@ -990,19 +919,19 @@ types-protobuf==3.19.22 # mypy-protobuf types-pymysql==1.1.0.1 # via feast (setup.py) -types-pyopenssl==23.2.0.2 +types-pyopenssl==23.3.0.0 # via types-redis types-python-dateutil==2.8.19.14 - # via feast (setup.py) -types-pytz==2023.3.0.1 - # via feast (setup.py) -types-pyyaml==6.0.12.11 # via + # arrow # feast (setup.py) - # responses -types-redis==4.6.0.5 +types-pytz==2023.3.1.1 + # via feast (setup.py) +types-pyyaml==6.0.12.12 + # via feast (setup.py) +types-redis==4.6.0.10 # via feast (setup.py) -types-requests==2.31.0.2 +types-requests==2.30.0.0 # via feast (setup.py) types-setuptools==68.2.0.0 # via feast (setup.py) @@ -1010,14 +939,13 @@ types-tabulate==0.9.0.3 # via feast (setup.py) types-urllib3==1.26.25.14 # via types-requests -typing-extensions==4.7.1 +typing-extensions==4.8.0 # via # async-lru # azure-core # azure-storage-blob # black # fastapi - # filelock # great-expectations # ipython # mypy @@ -1026,7 +954,7 @@ typing-extensions==4.7.1 # sqlalchemy2-stubs # starlette # uvicorn -tzlocal==5.0.1 +tzlocal==5.2 # via # great-expectations # trino @@ -1039,7 +967,6 @@ urllib3==1.26.18 # botocore # docker # feast (setup.py) - # google-auth # great-expectations # kubernetes # minio @@ -1047,9 +974,9 @@ urllib3==1.26.18 # responses # rockset # snowflake-connector-python -uvicorn[standard]==0.23.2 +uvicorn[standard]==0.24.0.post1 # via feast (setup.py) -uvloop==0.17.0 +uvloop==0.19.0 # via uvicorn virtualenv==20.23.0 # via @@ -1057,9 +984,9 @@ virtualenv==20.23.0 # pre-commit volatile==2.1.0 # via bowler -watchfiles==0.20.0 +watchfiles==0.21.0 # via uvicorn -wcwidth==0.2.6 +wcwidth==0.2.9 # via prompt-toolkit webcolors==1.13 # via jsonschema @@ -1067,26 +994,24 @@ webencodings==0.5.1 # via # bleach # tinycss2 -websocket-client==1.6.2 +websocket-client==1.6.4 # via # docker # jupyter-server # kubernetes -websockets==11.0.3 +websockets==12.0 # via uvicorn -werkzeug==2.3.7 +werkzeug==3.0.1 # via moto -wheel==0.41.2 +wheel==0.41.3 # via pip-tools -widgetsnbextension==4.0.8 +widgetsnbextension==4.0.9 # via ipywidgets wrapt==1.15.0 # via testcontainers xmltodict==0.13.0 # via moto -yarl==1.9.2 - # via aiohttp -zipp==3.16.2 +zipp==3.17.0 # via # importlib-metadata # importlib-resources diff --git a/sdk/python/requirements/py3.8-requirements.txt b/sdk/python/requirements/py3.8-requirements.txt index ec4a9f5187f..174dc7d6f52 100644 --- a/sdk/python/requirements/py3.8-requirements.txt +++ b/sdk/python/requirements/py3.8-requirements.txt @@ -6,7 +6,7 @@ # anyio==4.0.0 # via - # httpcore + # httpx # starlette # watchfiles appdirs==1.4.4 @@ -23,7 +23,7 @@ certifi==2023.7.22 # httpcore # httpx # requests -charset-normalizer==3.2.0 +charset-normalizer==3.3.2 # via requests click==8.1.7 # via @@ -32,7 +32,7 @@ click==8.1.7 # feast (setup.py) # moreorless # uvicorn -cloudpickle==2.2.1 +cloudpickle==3.0.0 # via dask colorama==0.4.6 # via feast (setup.py) @@ -44,25 +44,27 @@ exceptiongroup==1.1.3 # via anyio fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.3 +fastavro==1.9.0 # via # feast (setup.py) # pandavro fissix==21.11.13 # via bowler -fsspec==2023.9.0 +fsspec==2023.10.0 # via dask -grpcio==1.58.0 +greenlet==3.0.1 + # via sqlalchemy +grpcio==1.59.2 # via # feast (setup.py) # grpcio-health-checking # grpcio-reflection # grpcio-tools -grpcio-health-checking==1.58.0 +grpcio-health-checking==1.59.2 # via feast (setup.py) -grpcio-reflection==1.58.0 +grpcio-reflection==1.59.2 # via feast (setup.py) -grpcio-tools==1.58.0 +grpcio-tools==1.59.2 # via feast (setup.py) gunicorn==21.2.0 # via feast (setup.py) @@ -70,11 +72,11 @@ h11==0.14.0 # via # httpcore # uvicorn -httpcore==0.17.3 +httpcore==1.0.1 # via httpx -httptools==0.6.0 +httptools==0.6.1 # via uvicorn -httpx==0.24.1 +httpx==0.25.1 # via feast (setup.py) idna==3.4 # via @@ -85,14 +87,14 @@ importlib-metadata==6.8.0 # via # dask # feast (setup.py) -importlib-resources==6.0.1 +importlib-resources==6.1.1 # via # feast (setup.py) # jsonschema # jsonschema-specifications jinja2==3.1.2 # via feast (setup.py) -jsonschema==4.19.0 +jsonschema==4.19.2 # via feast (setup.py) jsonschema-specifications==2023.7.1 # via jsonschema @@ -104,7 +106,7 @@ mmh3==4.0.1 # via feast (setup.py) moreorless==0.4.0 # via bowler -mypy==1.5.1 +mypy==1.6.1 # via sqlalchemy mypy-extensions==1.0.0 # via mypy @@ -116,7 +118,7 @@ numpy==1.24.4 # pandas # pandavro # pyarrow -packaging==23.1 +packaging==23.2 # via # dask # gunicorn @@ -126,7 +128,7 @@ pandas==1.5.3 # pandavro pandavro==1.5.2 # via feast (setup.py) -partd==1.4.0 +partd==1.4.1 # via dask pkgutil-resolve-name==1.3.10 # via jsonschema @@ -142,7 +144,7 @@ protobuf==4.23.3 # proto-plus pyarrow==11.0.0 # via feast (setup.py) -pydantic==1.10.12 +pydantic==1.10.13 # via # fastapi # feast (setup.py) @@ -165,7 +167,7 @@ referencing==0.30.2 # jsonschema-specifications requests==2.31.0 # via feast (setup.py) -rpds-py==0.10.2 +rpds-py==0.12.0 # via # jsonschema # referencing @@ -176,11 +178,10 @@ six==1.16.0 sniffio==1.3.0 # via # anyio - # httpcore # httpx -sqlalchemy[mypy]==1.4.49 +sqlalchemy[mypy]==1.4.50 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a35 +sqlalchemy2-stubs==0.0.2a36 # via sqlalchemy starlette==0.27.0 # via fastapi @@ -200,9 +201,9 @@ tqdm==4.66.1 # via feast (setup.py) typeguard==2.13.3 # via feast (setup.py) -types-protobuf==4.24.0.1 +types-protobuf==4.24.0.4 # via mypy-protobuf -typing-extensions==4.7.1 +typing-extensions==4.8.0 # via # fastapi # mypy @@ -210,19 +211,19 @@ typing-extensions==4.7.1 # sqlalchemy2-stubs # starlette # uvicorn -urllib3==1.26.18 +urllib3==2.0.7 # via requests -uvicorn[standard]==0.23.2 +uvicorn[standard]==0.24.0.post1 # via feast (setup.py) -uvloop==0.17.0 +uvloop==0.19.0 # via uvicorn volatile==2.1.0 # via bowler -watchfiles==0.20.0 +watchfiles==0.21.0 # via uvicorn -websockets==11.0.3 +websockets==12.0 # via uvicorn -zipp==3.16.2 +zipp==3.17.0 # via # importlib-metadata # importlib-resources diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index aee80ca040d..4bf35b4adfe 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -4,93 +4,64 @@ # # pip-compile --extra=ci --output-file=sdk/python/requirements/py3.9-ci-requirements.txt # -adal==1.2.7 - # via msrestazure -adlfs==0.5.9 - # via feast (setup.py) -aiohttp==3.8.5 - # via - # adlfs - # gcsfs -aiosignal==1.3.1 - # via aiohttp alabaster==0.7.13 # via sphinx altair==4.2.0 # via great-expectations anyio==4.0.0 # via - # httpcore + # httpx # jupyter-server # starlette # watchfiles appdirs==1.4.4 # via fissix -appnope==0.1.3 - # via - # ipykernel - # ipython argon2-cffi==23.1.0 # via jupyter-server argon2-cffi-bindings==21.2.0 # via argon2-cffi -arrow==1.2.3 +arrow==1.3.0 # via isoduration asn1crypto==1.5.1 - # via - # oscrypto - # snowflake-connector-python + # via snowflake-connector-python assertpy==1.1 # via feast (setup.py) -asttokens==2.4.0 +asttokens==2.4.1 # via stack-data async-lru==2.0.4 # via jupyterlab async-timeout==4.0.3 - # via - # aiohttp - # redis + # via redis attrs==23.1.0 # via - # aiohttp # bowler # jsonschema # referencing -avro==1.11.3 +avro==1.10.0 # via feast (setup.py) -azure-core==1.29.4 +azure-core==1.29.5 # via - # adlfs # azure-identity # azure-storage-blob - # msrest -azure-datalake-store==0.0.53 - # via adlfs -azure-identity==1.14.0 - # via - # adlfs - # feast (setup.py) -azure-storage-blob==12.17.0 - # via - # adlfs - # feast (setup.py) -babel==2.12.1 +azure-identity==1.15.0 + # via feast (setup.py) +azure-storage-blob==12.19.0 + # via feast (setup.py) +babel==2.13.1 # via # jupyterlab-server # sphinx -backcall==0.2.0 - # via ipython beautifulsoup4==4.12.2 # via nbconvert black==22.12.0 # via feast (setup.py) -bleach==6.0.0 +bleach==6.1.0 # via nbconvert -boto3==1.28.43 +boto3==1.28.80 # via # feast (setup.py) # moto -botocore==1.31.43 +botocore==1.31.80 # via # boto3 # moto @@ -105,7 +76,7 @@ bytewax==0.15.1 # via feast (setup.py) cachecontrol==0.13.1 # via firebase-admin -cachetools==5.3.1 +cachetools==5.3.2 # via google-auth cassandra-driver==3.28.0 # via feast (setup.py) @@ -115,20 +86,17 @@ certifi==2023.7.22 # httpx # kubernetes # minio - # msrest # requests # snowflake-connector-python -cffi==1.15.1 +cffi==1.16.0 # via # argon2-cffi-bindings - # azure-datalake-store # cryptography # snowflake-connector-python cfgv==3.4.0 # via pre-commit -charset-normalizer==3.2.0 +charset-normalizer==3.3.2 # via - # aiohttp # requests # snowflake-connector-python click==8.1.7 @@ -142,21 +110,20 @@ click==8.1.7 # moreorless # pip-tools # uvicorn -cloudpickle==2.2.1 +cloudpickle==3.0.0 # via dask colorama==0.4.6 # via # feast (setup.py) # great-expectations -comm==0.1.4 +comm==0.2.0 # via # ipykernel # ipywidgets -coverage[toml]==7.3.1 +coverage[toml]==7.3.2 # via pytest-cov -cryptography==41.0.4 +cryptography==41.0.5 # via - # adal # azure-identity # azure-storage-blob # feast (setup.py) @@ -168,16 +135,14 @@ cryptography==41.0.4 # snowflake-connector-python # types-pyopenssl # types-redis -dask==2023.9.1 +dask==2023.10.1 # via feast (setup.py) db-dtypes==1.1.1 # via google-cloud-bigquery -debugpy==1.7.0 +debugpy==1.8.0 # via ipykernel decorator==5.1.1 - # via - # gcsfs - # ipython + # via ipython defusedxml==0.7.1 # via nbconvert deprecation==2.1.0 @@ -204,17 +169,17 @@ exceptiongroup==1.1.3 # pytest execnet==2.0.2 # via pytest-xdist -executing==1.2.0 +executing==2.0.1 # via stack-data fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.3 +fastavro==1.9.0 # via # feast (setup.py) # pandavro -fastjsonschema==2.18.0 +fastjsonschema==2.18.1 # via nbformat -filelock==3.12.3 +filelock==3.13.1 # via # snowflake-connector-python # virtualenv @@ -226,22 +191,15 @@ flake8==6.0.0 # via feast (setup.py) fqdn==1.5.1 # via jsonschema -frozenlist==1.4.0 +fsspec==2023.9.2 # via - # aiohttp - # aiosignal -fsspec==2022.1.0 - # via - # adlfs # dask - # gcsfs -gcsfs==2022.1.0 - # via feast (setup.py) + # feast (setup.py) geojson==2.5.0 # via rockset geomet==0.2.1.post1 # via cassandra-driver -google-api-core[grpc]==2.11.1 +google-api-core[grpc]==2.13.0 # via # feast (setup.py) # firebase-admin @@ -253,23 +211,19 @@ google-api-core[grpc]==2.11.1 # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.98.0 +google-api-python-client==2.107.0 # via firebase-admin -google-auth==2.22.0 +google-auth==2.23.4 # via - # gcsfs # google-api-core # google-api-python-client # google-auth-httplib2 - # google-auth-oauthlib # google-cloud-core # google-cloud-storage # kubernetes -google-auth-httplib2==0.1.0 +google-auth-httplib2==0.1.1 # via google-api-python-client -google-auth-oauthlib==1.0.0 - # via gcsfs -google-cloud-bigquery[pandas]==3.11.4 +google-cloud-bigquery[pandas]==3.12.0 # via feast (setup.py) google-cloud-bigquery-storage==2.22.0 # via feast (setup.py) @@ -284,20 +238,21 @@ google-cloud-core==2.3.3 # google-cloud-storage google-cloud-datastore==2.18.0 # via feast (setup.py) -google-cloud-firestore==2.11.1 +google-cloud-firestore==2.13.1 # via firebase-admin -google-cloud-storage==2.10.0 +google-cloud-storage==2.13.0 # via # feast (setup.py) # firebase-admin - # gcsfs google-crc32c==1.5.0 - # via google-resumable-media + # via + # google-cloud-storage + # google-resumable-media google-resumable-media==2.6.0 # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.60.0 +googleapis-common-protos[grpc]==1.61.0 # via # feast (setup.py) # google-api-core @@ -305,9 +260,11 @@ googleapis-common-protos[grpc]==1.60.0 # grpcio-status great-expectations==0.15.50 # via feast (setup.py) +greenlet==3.0.1 + # via sqlalchemy grpc-google-iam-v1==0.12.6 # via google-cloud-bigtable -grpcio==1.58.0 +grpcio==1.59.2 # via # feast (setup.py) # google-api-core @@ -319,15 +276,15 @@ grpcio==1.58.0 # grpcio-status # grpcio-testing # grpcio-tools -grpcio-health-checking==1.58.0 +grpcio-health-checking==1.59.2 # via feast (setup.py) -grpcio-reflection==1.58.0 +grpcio-reflection==1.59.2 # via feast (setup.py) -grpcio-status==1.58.0 +grpcio-status==1.59.2 # via google-api-core -grpcio-testing==1.58.0 +grpcio-testing==1.59.2 # via feast (setup.py) -grpcio-tools==1.58.0 +grpcio-tools==1.59.2 # via feast (setup.py) gunicorn==21.2.0 # via feast (setup.py) @@ -341,17 +298,17 @@ hazelcast-python-client==5.3.0 # via feast (setup.py) hiredis==2.2.3 # via feast (setup.py) -httpcore==0.17.3 +httpcore==1.0.1 # via httpx httplib2==0.22.0 # via # google-api-python-client # google-auth-httplib2 -httptools==0.6.0 +httptools==0.6.1 # via uvicorn -httpx==0.24.1 +httpx==0.25.1 # via feast (setup.py) -identify==2.5.27 +identify==2.5.31 # via pre-commit idna==3.4 # via @@ -360,7 +317,6 @@ idna==3.4 # jsonschema # requests # snowflake-connector-python - # yarl imagesize==1.4.1 # via sphinx importlib-metadata==6.8.0 @@ -375,28 +331,26 @@ importlib-metadata==6.8.0 # jupyterlab-server # nbconvert # sphinx -importlib-resources==6.0.1 +importlib-resources==6.1.1 # via feast (setup.py) iniconfig==2.0.0 # via pytest -ipykernel==6.25.2 +ipykernel==6.26.0 # via jupyterlab -ipython==8.15.0 +ipython==8.17.2 # via # great-expectations # ipykernel # ipywidgets -ipywidgets==8.1.0 +ipywidgets==8.1.1 # via great-expectations isodate==0.6.1 - # via - # azure-storage-blob - # msrest + # via azure-storage-blob isoduration==20.11.0 # via jsonschema isort==5.12.0 # via feast (setup.py) -jedi==0.19.0 +jedi==0.19.1 # via ipython jinja2==3.1.2 # via @@ -421,7 +375,7 @@ jsonpointer==2.4 # via # jsonpatch # jsonschema -jsonschema[format-nongpl]==4.19.0 +jsonschema[format-nongpl]==4.19.2 # via # altair # feast (setup.py) @@ -431,12 +385,12 @@ jsonschema[format-nongpl]==4.19.0 # nbformat jsonschema-specifications==2023.7.1 # via jsonschema -jupyter-client==8.3.1 +jupyter-client==8.6.0 # via # ipykernel # jupyter-server # nbclient -jupyter-core==5.3.1 +jupyter-core==5.5.0 # via # ipykernel # jupyter-client @@ -445,11 +399,11 @@ jupyter-core==5.3.1 # nbclient # nbconvert # nbformat -jupyter-events==0.7.0 +jupyter-events==0.9.0 # via jupyter-server jupyter-lsp==2.2.0 # via jupyterlab -jupyter-server==2.7.3 +jupyter-server==2.10.0 # via # jupyter-lsp # jupyterlab @@ -458,15 +412,15 @@ jupyter-server==2.7.3 # notebook-shim jupyter-server-terminals==0.4.4 # via jupyter-server -jupyterlab==4.0.5 +jupyterlab==4.0.8 # via notebook jupyterlab-pygments==0.2.2 # via nbconvert -jupyterlab-server==2.24.0 +jupyterlab-server==2.25.0 # via # jupyterlab # notebook -jupyterlab-widgets==3.0.8 +jupyterlab-widgets==3.0.9 # via ipywidgets kubernetes==20.13.0 # via feast (setup.py) @@ -489,7 +443,7 @@ mccabe==0.7.0 # via flake8 minio==7.1.0 # via feast (setup.py) -mistune==3.0.1 +mistune==3.0.2 # via # great-expectations # nbconvert @@ -499,25 +453,16 @@ mock==2.0.0 # via feast (setup.py) moreorless==0.4.0 # via bowler -moto==4.2.2 +moto==4.2.7 # via feast (setup.py) -msal==1.23.0 +msal==1.25.0 # via - # azure-datalake-store # azure-identity # msal-extensions msal-extensions==1.0.0 # via azure-identity -msgpack==1.0.5 +msgpack==1.0.7 # via cachecontrol -msrest==0.7.1 - # via msrestazure -msrestazure==0.6.4 - # via adlfs -multidict==6.0.4 - # via - # aiohttp - # yarl multiprocess==0.70.15 # via bytewax mypy==0.982 @@ -528,13 +473,13 @@ mypy-extensions==1.0.0 # via # black # mypy -mypy-protobuf==3.1.0 +mypy-protobuf==3.1 # via feast (setup.py) mysqlclient==2.2.0 # via feast (setup.py) -nbclient==0.8.0 +nbclient==0.9.0 # via nbconvert -nbconvert==7.8.0 +nbconvert==7.11.0 # via jupyter-server nbformat==5.9.2 # via @@ -542,11 +487,11 @@ nbformat==5.9.2 # jupyter-server # nbclient # nbconvert -nest-asyncio==1.5.7 +nest-asyncio==1.5.8 # via ipykernel nodeenv==1.8.0 # via pre-commit -notebook==7.0.3 +notebook==7.0.6 # via great-expectations notebook-shim==0.2.3 # via @@ -564,11 +509,9 @@ numpy==1.24.4 # scipy oauthlib==3.2.2 # via requests-oauthlib -oscrypto==1.3.0 - # via snowflake-connector-python overrides==7.4.0 # via jupyter-server -packaging==23.1 +packaging==23.2 # via # build # dask @@ -602,19 +545,17 @@ pandocfilters==1.5.0 # via nbconvert parso==0.8.3 # via jedi -partd==1.4.0 +partd==1.4.1 # via dask pathspec==0.11.2 # via black -pbr==5.11.1 +pbr==6.0.0 # via mock pexpect==4.8.0 # via ipython -pickleshare==0.7.5 - # via ipython pip-tools==7.3.0 # via feast (setup.py) -platformdirs==3.8.1 +platformdirs==3.11.0 # via # black # jupyter-core @@ -624,11 +565,11 @@ pluggy==1.3.0 # via pytest ply==3.11 # via thriftpy2 -portalocker==2.7.0 +portalocker==2.8.2 # via msal-extensions pre-commit==3.3.1 # via feast (setup.py) -prometheus-client==0.17.1 +prometheus-client==0.18.0 # via jupyter-server prompt-toolkit==3.0.39 # via ipython @@ -662,7 +603,7 @@ psutil==5.9.0 # via # feast (setup.py) # ipykernel -psycopg2-binary==2.9.7 +psycopg2-binary==2.9.9 # via feast (setup.py) ptyprocess==0.7.0 # via @@ -694,9 +635,7 @@ pycodestyle==2.10.0 # via flake8 pycparser==2.21 # via cffi -pycryptodomex==3.18.0 - # via snowflake-connector-python -pydantic==1.10.12 +pydantic==1.10.13 # via # fastapi # feast (setup.py) @@ -711,16 +650,15 @@ pygments==2.16.1 # sphinx pyjwt[crypto]==2.8.0 # via - # adal # msal # snowflake-connector-python -pymssql==2.2.8 +pymssql==2.2.10 # via feast (setup.py) pymysql==1.1.0 # via feast (setup.py) -pyodbc==4.0.39 +pyodbc==5.0.1 # via feast (setup.py) -pyopenssl==23.2.0 +pyopenssl==23.3.0 # via snowflake-connector-python pyparsing==3.1.1 # via @@ -728,9 +666,9 @@ pyparsing==3.1.1 # httplib2 pyproject-hooks==1.0.0 # via build -pyspark==3.4.1 +pyspark==3.5.0 # via feast (setup.py) -pytest==7.4.2 +pytest==7.4.3 # via # feast (setup.py) # pytest-benchmark @@ -756,7 +694,6 @@ pytest-xdist==3.3.1 # via feast (setup.py) python-dateutil==2.8.2 # via - # adal # arrow # botocore # google-cloud-bigquery @@ -798,18 +735,14 @@ referencing==0.30.2 # jsonschema # jsonschema-specifications # jupyter-events -regex==2023.8.8 +regex==2023.10.3 # via feast (setup.py) requests==2.31.0 # via - # adal - # adlfs # azure-core - # azure-datalake-store # cachecontrol # docker # feast (setup.py) - # gcsfs # google-api-core # google-cloud-bigquery # google-cloud-storage @@ -818,18 +751,14 @@ requests==2.31.0 # kubernetes # moto # msal - # msrest # requests-oauthlib # responses # snowflake-connector-python # sphinx # trino requests-oauthlib==1.3.1 - # via - # google-auth-oauthlib - # kubernetes - # msrest -responses==0.23.3 + # via kubernetes +responses==0.24.0 # via moto rfc3339-validator==0.1.4 # via @@ -841,7 +770,7 @@ rfc3986-validator==0.1.1 # jupyter-events rockset==2.1.0 # via feast (setup.py) -rpds-py==0.10.2 +rpds-py==0.12.0 # via # jsonschema # referencing @@ -849,11 +778,11 @@ rsa==4.9 # via google-auth ruamel-yaml==0.17.17 # via great-expectations -ruamel-yaml-clib==0.2.7 +ruamel-yaml-clib==0.2.8 # via ruamel-yaml -s3transfer==0.6.2 +s3transfer==0.7.0 # via boto3 -scipy==1.11.2 +scipy==1.11.3 # via great-expectations send2trash==1.8.2 # via jupyter-server @@ -864,13 +793,10 @@ six==1.16.0 # bleach # cassandra-driver # geomet - # google-auth - # google-auth-httplib2 # happybase # isodate # kubernetes # mock - # msrestazure # pandavro # python-dateutil # rfc3339-validator @@ -878,11 +804,10 @@ six==1.16.0 sniffio==1.3.0 # via # anyio - # httpcore # httpx snowballstemmer==2.2.0 # via sphinx -snowflake-connector-python[pandas]==3.1.1 +snowflake-connector-python[pandas]==3.4.0 # via feast (setup.py) sortedcontainers==2.4.0 # via snowflake-connector-python @@ -908,11 +833,11 @@ sphinxcontrib-qthelp==1.0.6 # via sphinx sphinxcontrib-serializinghtml==1.1.9 # via sphinx -sqlalchemy[mypy]==1.4.49 +sqlalchemy[mypy]==1.4.50 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a35 +sqlalchemy2-stubs==0.0.2a36 # via sqlalchemy -stack-data==0.6.2 +stack-data==0.6.3 # via ipython starlette==0.27.0 # via fastapi @@ -926,7 +851,7 @@ terminado==0.17.1 # jupyter-server-terminals testcontainers==3.7.1 # via feast (setup.py) -thriftpy2==0.4.16 +thriftpy2==0.4.17 # via happybase tinycss2==1.2.1 # via nbconvert @@ -942,7 +867,7 @@ tomli==2.0.1 # pip-tools # pyproject-hooks # pytest -tomlkit==0.12.1 +tomlkit==0.12.2 # via snowflake-connector-python toolz==0.12.0 # via @@ -961,7 +886,7 @@ tqdm==4.66.1 # via # feast (setup.py) # great-expectations -traitlets==5.9.0 +traitlets==5.13.0 # via # comm # ipykernel @@ -976,7 +901,7 @@ traitlets==5.9.0 # nbclient # nbconvert # nbformat -trino==0.326.0 +trino==0.327.0 # via feast (setup.py) typeguard==2.13.3 # via feast (setup.py) @@ -986,19 +911,19 @@ types-protobuf==3.19.22 # mypy-protobuf types-pymysql==1.1.0.1 # via feast (setup.py) -types-pyopenssl==23.2.0.2 +types-pyopenssl==23.3.0.0 # via types-redis types-python-dateutil==2.8.19.14 - # via feast (setup.py) -types-pytz==2023.3.0.1 - # via feast (setup.py) -types-pyyaml==6.0.12.11 # via + # arrow # feast (setup.py) - # responses -types-redis==4.6.0.5 +types-pytz==2023.3.1.1 + # via feast (setup.py) +types-pyyaml==6.0.12.12 + # via feast (setup.py) +types-redis==4.6.0.10 # via feast (setup.py) -types-requests==2.31.0.2 +types-requests==2.30.0.0 # via feast (setup.py) types-setuptools==68.2.0.0 # via feast (setup.py) @@ -1006,14 +931,13 @@ types-tabulate==0.9.0.3 # via feast (setup.py) types-urllib3==1.26.25.14 # via types-requests -typing-extensions==4.7.1 +typing-extensions==4.8.0 # via # async-lru # azure-core # azure-storage-blob # black # fastapi - # filelock # great-expectations # ipython # mypy @@ -1022,7 +946,7 @@ typing-extensions==4.7.1 # sqlalchemy2-stubs # starlette # uvicorn -tzlocal==5.0.1 +tzlocal==5.2 # via # great-expectations # trino @@ -1035,7 +959,6 @@ urllib3==1.26.18 # botocore # docker # feast (setup.py) - # google-auth # great-expectations # kubernetes # minio @@ -1043,9 +966,9 @@ urllib3==1.26.18 # responses # rockset # snowflake-connector-python -uvicorn[standard]==0.23.2 +uvicorn[standard]==0.24.0.post1 # via feast (setup.py) -uvloop==0.17.0 +uvloop==0.19.0 # via uvicorn virtualenv==20.23.0 # via @@ -1053,9 +976,9 @@ virtualenv==20.23.0 # pre-commit volatile==2.1.0 # via bowler -watchfiles==0.20.0 +watchfiles==0.21.0 # via uvicorn -wcwidth==0.2.6 +wcwidth==0.2.9 # via prompt-toolkit webcolors==1.13 # via jsonschema @@ -1063,26 +986,24 @@ webencodings==0.5.1 # via # bleach # tinycss2 -websocket-client==1.6.2 +websocket-client==1.6.4 # via # docker # jupyter-server # kubernetes -websockets==11.0.3 +websockets==12.0 # via uvicorn -werkzeug==2.3.7 +werkzeug==3.0.1 # via moto -wheel==0.41.2 +wheel==0.41.3 # via pip-tools -widgetsnbextension==4.0.8 +widgetsnbextension==4.0.9 # via ipywidgets wrapt==1.15.0 # via testcontainers xmltodict==0.13.0 # via moto -yarl==1.9.2 - # via aiohttp -zipp==3.16.2 +zipp==3.17.0 # via # importlib-metadata # importlib-resources diff --git a/sdk/python/requirements/py3.9-requirements.txt b/sdk/python/requirements/py3.9-requirements.txt index 81a8afa699a..12612c34657 100644 --- a/sdk/python/requirements/py3.9-requirements.txt +++ b/sdk/python/requirements/py3.9-requirements.txt @@ -6,7 +6,7 @@ # anyio==4.0.0 # via - # httpcore + # httpx # starlette # watchfiles appdirs==1.4.4 @@ -23,7 +23,7 @@ certifi==2023.7.22 # httpcore # httpx # requests -charset-normalizer==3.2.0 +charset-normalizer==3.3.2 # via requests click==8.1.7 # via @@ -32,11 +32,11 @@ click==8.1.7 # feast (setup.py) # moreorless # uvicorn -cloudpickle==2.2.1 +cloudpickle==3.0.0 # via dask colorama==0.4.6 # via feast (setup.py) -dask==2023.9.1 +dask==2023.10.1 # via feast (setup.py) dill==0.3.7 # via feast (setup.py) @@ -44,25 +44,27 @@ exceptiongroup==1.1.3 # via anyio fastapi==0.99.1 # via feast (setup.py) -fastavro==1.8.3 +fastavro==1.9.0 # via # feast (setup.py) # pandavro fissix==21.11.13 # via bowler -fsspec==2023.9.0 +fsspec==2023.10.0 # via dask -grpcio==1.58.0 +greenlet==3.0.1 + # via sqlalchemy +grpcio==1.59.2 # via # feast (setup.py) # grpcio-health-checking # grpcio-reflection # grpcio-tools -grpcio-health-checking==1.58.0 +grpcio-health-checking==1.59.2 # via feast (setup.py) -grpcio-reflection==1.58.0 +grpcio-reflection==1.59.2 # via feast (setup.py) -grpcio-tools==1.58.0 +grpcio-tools==1.59.2 # via feast (setup.py) gunicorn==21.2.0 # via feast (setup.py) @@ -70,11 +72,11 @@ h11==0.14.0 # via # httpcore # uvicorn -httpcore==0.17.3 +httpcore==1.0.1 # via httpx -httptools==0.6.0 +httptools==0.6.1 # via uvicorn -httpx==0.24.1 +httpx==0.25.1 # via feast (setup.py) idna==3.4 # via @@ -85,11 +87,11 @@ importlib-metadata==6.8.0 # via # dask # feast (setup.py) -importlib-resources==6.0.1 +importlib-resources==6.1.1 # via feast (setup.py) jinja2==3.1.2 # via feast (setup.py) -jsonschema==4.19.0 +jsonschema==4.19.2 # via feast (setup.py) jsonschema-specifications==2023.7.1 # via jsonschema @@ -101,11 +103,11 @@ mmh3==4.0.1 # via feast (setup.py) moreorless==0.4.0 # via bowler -mypy==1.5.1 +mypy==1.6.1 # via sqlalchemy mypy-extensions==1.0.0 # via mypy -mypy-protobuf==3.1.0 +mypy-protobuf==3.1 # via feast (setup.py) numpy==1.24.4 # via @@ -113,7 +115,7 @@ numpy==1.24.4 # pandas # pandavro # pyarrow -packaging==23.1 +packaging==23.2 # via # dask # gunicorn @@ -123,7 +125,7 @@ pandas==1.5.3 # pandavro pandavro==1.5.2 # via feast (setup.py) -partd==1.4.0 +partd==1.4.1 # via dask proto-plus==1.22.3 # via feast (setup.py) @@ -137,7 +139,7 @@ protobuf==4.23.3 # proto-plus pyarrow==11.0.0 # via feast (setup.py) -pydantic==1.10.12 +pydantic==1.10.13 # via # fastapi # feast (setup.py) @@ -160,7 +162,7 @@ referencing==0.30.2 # jsonschema-specifications requests==2.31.0 # via feast (setup.py) -rpds-py==0.10.2 +rpds-py==0.12.0 # via # jsonschema # referencing @@ -171,11 +173,10 @@ six==1.16.0 sniffio==1.3.0 # via # anyio - # httpcore # httpx -sqlalchemy[mypy]==1.4.49 +sqlalchemy[mypy]==1.4.50 # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a35 +sqlalchemy2-stubs==0.0.2a36 # via sqlalchemy starlette==0.27.0 # via fastapi @@ -195,9 +196,9 @@ tqdm==4.66.1 # via feast (setup.py) typeguard==2.13.3 # via feast (setup.py) -types-protobuf==4.24.0.1 +types-protobuf==4.24.0.4 # via mypy-protobuf -typing-extensions==4.7.1 +typing-extensions==4.8.0 # via # fastapi # mypy @@ -205,19 +206,19 @@ typing-extensions==4.7.1 # sqlalchemy2-stubs # starlette # uvicorn -urllib3==1.26.18 +urllib3==2.0.7 # via requests -uvicorn[standard]==0.23.2 +uvicorn[standard]==0.24.0.post1 # via feast (setup.py) -uvloop==0.17.0 +uvloop==0.19.0 # via uvicorn volatile==2.1.0 # via bowler -watchfiles==0.20.0 +watchfiles==0.21.0 # via uvicorn -websockets==11.0.3 +websockets==12.0 # via uvicorn -zipp==3.16.2 +zipp==3.17.0 # via # importlib-metadata # importlib-resources From 1278b357835a9f645d544d77718445bc060e57c3 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Sat, 4 Nov 2023 11:07:07 +0700 Subject: [PATCH 075/113] feat: Optimize bytewax pod resource with zero-copy Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- .../bytewax_materialization_dataflow.py | 41 ++++++++----------- .../bytewax/bytewax_materialization_engine.py | 14 +++++-- .../contrib/bytewax/dataflow.py | 3 ++ 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py index 31be7a6b893..6fc53b67f2f 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_dataflow.py @@ -1,3 +1,4 @@ +import logging import os from typing import List @@ -7,11 +8,11 @@ from bytewax.execution import cluster_main from bytewax.inputs import ManualInputConfig from bytewax.outputs import ManualOutputConfig -from tqdm import tqdm from feast import FeatureStore, FeatureView, RepoConfig from feast.utils import _convert_arrow_to_proto, _run_pyarrow_field_mapping +logger = logging.getLogger(__name__) DEFAULT_BATCH_SIZE = 1000 @@ -29,14 +30,20 @@ def __init__( self.feature_view = feature_view self.worker_index = worker_index self.paths = paths + self.mini_batch_size = int( + os.getenv("BYTEWAX_MINI_BATCH_SIZE", DEFAULT_BATCH_SIZE) + ) self._run_dataflow() def process_path(self, path): + logger.info(f"Processing path {path}") dataset = pq.ParquetDataset(path, use_legacy_dataset=False) batches = [] for fragment in dataset.fragments: - for batch in fragment.to_table().to_batches(): + for batch in fragment.to_table().to_batches( + max_chunksize=self.mini_batch_size + ): batches.append(batch) return batches @@ -45,40 +52,26 @@ def input_builder(self, worker_index, worker_count, _state): return [(None, self.paths[self.worker_index])] def output_builder(self, worker_index, worker_count): - def yield_batch(iterable, batch_size): - """Yield mini-batches from an iterable.""" - for i in range(0, len(iterable), batch_size): - yield iterable[i : i + batch_size] - - def output_fn(batch): - table = pa.Table.from_batches([batch]) + def output_fn(mini_batch): + table: pa.Table = pa.Table.from_batches([mini_batch]) if self.feature_view.batch_source.field_mapping is not None: table = _run_pyarrow_field_mapping( table, self.feature_view.batch_source.field_mapping ) - join_key_to_value_type = { entity.name: entity.dtype.to_value_type() for entity in self.feature_view.entity_columns } - rows_to_write = _convert_arrow_to_proto( table, self.feature_view, join_key_to_value_type ) - provider = self.feature_store._get_provider() - with tqdm(total=len(rows_to_write)) as progress: - # break rows_to_write to mini-batches - batch_size = int( - os.getenv("BYTEWAX_MINI_BATCH_SIZE", DEFAULT_BATCH_SIZE) - ) - for mini_batch in yield_batch(rows_to_write, batch_size): - provider.online_write_batch( - config=self.config, - table=self.feature_view, - data=mini_batch, - progress=progress.update, - ) + self.feature_store._get_provider().online_write_batch( + config=self.config, + table=self.feature_view, + data=rows_to_write, + progress=None, + ) return output_fn diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py index b2f8985f876..16742ff0f73 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py @@ -82,6 +82,12 @@ class BytewaxMaterializationEngineConfig(FeastConfigBaseModel): mini_batch_size: int = 1000 """ (optional) Number of rows to process per write operation (default 1000)""" + bytewax_replicas: int = 5 + """ (optional) Number of process to spawn in each pods to handle a file in parallel""" + + bytewax_worker_per_process: int = 1 + """ (optional) Number of threads as worker per bytewax process""" + active_deadline_seconds: int = 86400 """ (optional) Maximum amount of time a materialization job is allowed to run""" @@ -111,7 +117,6 @@ def __init__( self.offline_store = offline_store self.online_store = online_store - # TODO: Configure k8s here k8s_config.load_config() self.k8s_client = client.api_client.ApiClient() @@ -299,6 +304,9 @@ def _create_kubernetes_job(self, job_id, paths, feature_view): len(paths), # Create a pod for each parquet file self.batch_engine_config.env, ) + logger.info( + f"Created job `dataflow-{job_id}` on namespace `{self.namespace}`" + ) except FailToCreateError as failures: return BytewaxMaterializationJob(job_id, self.namespace, error=failures) @@ -345,7 +353,7 @@ def _create_job_definition(self, job_id, namespace, pods, env, index_offset=0): {"name": "BYTEWAX_WORKDIR", "value": "/bytewax"}, { "name": "BYTEWAX_WORKERS_PER_PROCESS", - "value": "1", + "value": f"{self.batch_engine_config.bytewax_worker_per_process}", }, { "name": "BYTEWAX_POD_NAME", @@ -358,7 +366,7 @@ def _create_job_definition(self, job_id, namespace, pods, env, index_offset=0): }, { "name": "BYTEWAX_REPLICAS", - "value": f"{pods}", + "value": f"{self.batch_engine_config.bytewax_replicas}", }, { "name": "BYTEWAX_KEEP_CONTAINER_ALIVE", diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py b/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py index 23cdc20ef36..9d9b328c0e9 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py @@ -1,3 +1,4 @@ +import logging import os import yaml @@ -8,6 +9,8 @@ ) if __name__ == "__main__": + logging.basicConfig(level=logging.INFO) + with open("/var/feast/feature_store.yaml") as f: feast_config = yaml.safe_load(f) From d900c55aede9c63a206afaa366c71201dcd03491 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Mon, 6 Nov 2023 16:19:22 +0700 Subject: [PATCH 076/113] fix: improve parsing bytewax job status Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- .../bytewax/bytewax_materialization_job.py | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_job.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_job.py index 4105be90ee7..da969d5a880 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_job.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_job.py @@ -35,13 +35,22 @@ def status(self): if job_status.active is not None: if job_status.completion_time is None: return MaterializationJobStatus.RUNNING - elif job_status.failed is not None: - self._error = Exception(f"Job {self.job_id()} failed") - return MaterializationJobStatus.ERROR - elif job_status.active is None: - if job_status.completion_time is not None: - if job_status.conditions[0].type == "Complete": - return MaterializationJobStatus.SUCCEEDED + else: + if ( + job_status.completion_time is not None + and job_status.conditions[0].type == "Complete" + ): + return MaterializationJobStatus.SUCCEEDED + + if ( + job_status.conditions is not None + and job_status.conditions[0].type == "Failed" + ): + self._error = Exception( + f"Job {self.job_id()} failed with reason: " + f"{job_status.conditions[0].message}" + ) + return MaterializationJobStatus.ERROR return MaterializationJobStatus.WAITING def should_be_retried(self): From 2a16bd73d4211d664371e4c70978d74378c5dacb Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Wed, 8 Nov 2023 13:42:39 +0700 Subject: [PATCH 077/113] fix: make bytewax settings unexposed Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- .../contrib/bytewax/bytewax_materialization_engine.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py index 16742ff0f73..5c7a719532d 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py @@ -82,12 +82,6 @@ class BytewaxMaterializationEngineConfig(FeastConfigBaseModel): mini_batch_size: int = 1000 """ (optional) Number of rows to process per write operation (default 1000)""" - bytewax_replicas: int = 5 - """ (optional) Number of process to spawn in each pods to handle a file in parallel""" - - bytewax_worker_per_process: int = 1 - """ (optional) Number of threads as worker per bytewax process""" - active_deadline_seconds: int = 86400 """ (optional) Maximum amount of time a materialization job is allowed to run""" @@ -353,7 +347,7 @@ def _create_job_definition(self, job_id, namespace, pods, env, index_offset=0): {"name": "BYTEWAX_WORKDIR", "value": "/bytewax"}, { "name": "BYTEWAX_WORKERS_PER_PROCESS", - "value": f"{self.batch_engine_config.bytewax_worker_per_process}", + "value": "1", }, { "name": "BYTEWAX_POD_NAME", @@ -366,7 +360,7 @@ def _create_job_definition(self, job_id, namespace, pods, env, index_offset=0): }, { "name": "BYTEWAX_REPLICAS", - "value": f"{self.batch_engine_config.bytewax_replicas}", + "value": "1", }, { "name": "BYTEWAX_KEEP_CONTAINER_ALIVE", From 69bcd58ad37631876e582e57b19dd5dc146c1ffe Mon Sep 17 00:00:00 2001 From: snowron Date: Thu, 2 Nov 2023 15:15:27 +0300 Subject: [PATCH 078/113] feat: add redis sentinel support Signed-off-by: snowron Signed-off-by: Attila Toth --- sdk/python/feast/infra/online_stores/redis.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sdk/python/feast/infra/online_stores/redis.py b/sdk/python/feast/infra/online_stores/redis.py index 83922068ac4..f928f7ff493 100644 --- a/sdk/python/feast/infra/online_stores/redis.py +++ b/sdk/python/feast/infra/online_stores/redis.py @@ -43,6 +43,7 @@ try: from redis import Redis from redis.cluster import ClusterNode, RedisCluster + from redis.sentinel import Sentinel except ImportError as e: from feast.errors import FeastExtrasDependencyImportError @@ -54,6 +55,7 @@ class RedisType(str, Enum): redis = "redis" redis_cluster = "redis_cluster" + redis_sentinel = "redis_sentinel" class RedisOnlineStoreConfig(FeastConfigBaseModel): @@ -65,6 +67,9 @@ class RedisOnlineStoreConfig(FeastConfigBaseModel): redis_type: RedisType = RedisType.redis """Redis type: redis or redis_cluster""" + sentinel_master: StrictStr = "mymaster" + """Sentinel's master name""" + connection_string: StrictStr = "localhost:6379" """Connection string containing the host, port, and configuration parameters for Redis format: host:port,parameter1,parameter2 eg. redis:6379,db=0 """ @@ -178,6 +183,19 @@ def _get_client(self, online_store_config: RedisOnlineStoreConfig): ClusterNode(**node) for node in startup_nodes ] self._client = RedisCluster(**kwargs) + elif online_store_config.redis_type == RedisType.redis_sentinel: + sentinel_hosts = [] + + for item in startup_nodes: + sentinel_hosts.append((item['host'], int(item['port']))) + + sentinel = Sentinel( + sentinel_hosts, + **kwargs + ) + + master = sentinel.master_for(online_store_config.sentinel_master) + self._client = master else: kwargs["host"] = startup_nodes[0]["host"] kwargs["port"] = startup_nodes[0]["port"] From 02b924228006a6ac0bb966989a720b013895518a Mon Sep 17 00:00:00 2001 From: snowron Date: Thu, 2 Nov 2023 15:22:55 +0300 Subject: [PATCH 079/113] feat: add redis sentinel support Signed-off-by: snowron Signed-off-by: Attila Toth --- docs/reference/online-stores/redis.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/reference/online-stores/redis.md b/docs/reference/online-stores/redis.md index c08cef2a3e1..ae7f8b4c5ca 100644 --- a/docs/reference/online-stores/redis.md +++ b/docs/reference/online-stores/redis.md @@ -45,6 +45,21 @@ online_store: ``` {% endcode %} +Connecting to a Redis Sentinel with SSL enabled and password authentication: + +{% code title="feature_store.yaml" %} +```yaml +project: my_feature_repo +registry: data/registry.db +provider: local +online_store: + type: redis + redis_type: redis_sentinel + sentinel_master: mymaster + connection_string: "redis1:26379,ssl=true,password=my_password" +``` +{% endcode %} + Additionally, the redis online store also supports automatically deleting data via a TTL mechanism. The TTL is applied at the entity level, so feature values from any associated feature views for an entity are removed together. This TTL can be set in the `feature_store.yaml`, using the `key_ttl_seconds` field in the online store. For example: From cdab45d4171bf37563b0ee58d082f4951c6d1bd0 Mon Sep 17 00:00:00 2001 From: snowron Date: Thu, 2 Nov 2023 16:20:42 +0300 Subject: [PATCH 080/113] feat: add redis sentinel support format lint Signed-off-by: snowron Signed-off-by: Attila Toth --- sdk/python/feast/infra/online_stores/redis.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sdk/python/feast/infra/online_stores/redis.py b/sdk/python/feast/infra/online_stores/redis.py index f928f7ff493..9561705aaac 100644 --- a/sdk/python/feast/infra/online_stores/redis.py +++ b/sdk/python/feast/infra/online_stores/redis.py @@ -187,13 +187,9 @@ def _get_client(self, online_store_config: RedisOnlineStoreConfig): sentinel_hosts = [] for item in startup_nodes: - sentinel_hosts.append((item['host'], int(item['port']))) + sentinel_hosts.append((item["host"], int(item["port"]))) - sentinel = Sentinel( - sentinel_hosts, - **kwargs - ) - + sentinel = Sentinel(sentinel_hosts, **kwargs) master = sentinel.master_for(online_store_config.sentinel_master) self._client = master else: From b8001f078fe3f96c85ed6751ff27fc1da6a388cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 22:54:18 +0000 Subject: [PATCH 081/113] chore: Bump pyarrow Bumps [pyarrow](https://github.com/apache/arrow) from 6.0.0 to 14.0.1. - [Commits](https://github.com/apache/arrow/compare/go/arrow/v6.0.0...apache-arrow-14.0.1) --- updated-dependencies: - dependency-name: pyarrow dependency-type: direct:production ... Signed-off-by: dependabot[bot] Signed-off-by: Attila Toth --- .../src/test/resources/docker-compose/feast10/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/serving/src/test/resources/docker-compose/feast10/requirements.txt b/java/serving/src/test/resources/docker-compose/feast10/requirements.txt index 94e4771de2a..6ba2c53d817 100644 --- a/java/serving/src/test/resources/docker-compose/feast10/requirements.txt +++ b/java/serving/src/test/resources/docker-compose/feast10/requirements.txt @@ -1,5 +1,5 @@ # for source generation -pyarrow==6.0.0 +pyarrow==14.0.1 # temp fixes proto-plus From 68851f59ee877cdbd9bab6b98786ea21a5f21a1e Mon Sep 17 00:00:00 2001 From: Shuchu Han Date: Fri, 17 Nov 2023 12:31:29 -0500 Subject: [PATCH 082/113] fix: upgrade the pyarrow to latest v14.0.1 for CVE-2023-47248. Signed-off-by: Shuchu Han Signed-off-by: Attila Toth --- .../feast/infra/offline_stores/bigquery.py | 12 ++- sdk/python/feast/infra/utils/aws_utils.py | 4 +- .../requirements/py3.10-ci-requirements.txt | 74 ++++++++++-------- .../requirements/py3.10-requirements.txt | 28 ++++--- .../requirements/py3.8-ci-requirements.txt | 72 ++++++++++-------- .../requirements/py3.8-requirements.txt | 26 ++++--- .../requirements/py3.9-ci-requirements.txt | 76 +++++++++++-------- .../requirements/py3.9-requirements.txt | 30 ++++---- setup.py | 2 +- 9 files changed, 188 insertions(+), 136 deletions(-) diff --git a/sdk/python/feast/infra/offline_stores/bigquery.py b/sdk/python/feast/infra/offline_stores/bigquery.py index 10c8aa783fb..b7910c391c7 100644 --- a/sdk/python/feast/infra/offline_stores/bigquery.py +++ b/sdk/python/feast/infra/offline_stores/bigquery.py @@ -353,7 +353,11 @@ def write_logged_features( return with tempfile.TemporaryFile() as parquet_temp_file: - pyarrow.parquet.write_table(table=data, where=parquet_temp_file) + # In Pyarrow v13.0, the parquet version was upgraded to v2.6 from v2.4. + # Set the coerce_timestamps to "us"(microseconds) for backward compatibility. + pyarrow.parquet.write_table( + table=data, where=parquet_temp_file, coerce_timestamps="us" + ) parquet_temp_file.seek(0) @@ -400,7 +404,11 @@ def offline_write_batch( ) with tempfile.TemporaryFile() as parquet_temp_file: - pyarrow.parquet.write_table(table=table, where=parquet_temp_file) + # In Pyarrow v13.0, the parquet version was upgraded to v2.6 from v2.4. + # Set the coerce_timestamps to "us"(microseconds) for backward compatibility. + pyarrow.parquet.write_table( + table=table, where=parquet_temp_file, coerce_timestamps="us" + ) parquet_temp_file.seek(0) diff --git a/sdk/python/feast/infra/utils/aws_utils.py b/sdk/python/feast/infra/utils/aws_utils.py index f48dfbb86b4..728bcab7914 100644 --- a/sdk/python/feast/infra/utils/aws_utils.py +++ b/sdk/python/feast/infra/utils/aws_utils.py @@ -351,7 +351,9 @@ def upload_arrow_table_to_redshift( else: # Write the PyArrow Table on disk in Parquet format and upload it to S3 with tempfile.TemporaryFile(suffix=".parquet") as parquet_temp_file: - pq.write_table(table, parquet_temp_file) + # In Pyarrow v13.0, the parquet version was upgraded to v2.6 from v2.4. + # Set the coerce_timestamps to "us"(microseconds) for backward compatibility. + pq.write_table(table, parquet_temp_file, coerce_timestamps="us") parquet_temp_file.seek(0) s3_resource.Object(bucket, key).put(Body=parquet_temp_file) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index c74a3f12e15..2cbfa6cbc96 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -57,11 +57,11 @@ black==22.12.0 # via feast (setup.py) bleach==6.1.0 # via nbconvert -boto3==1.28.80 +boto3==1.29.2 # via # feast (setup.py) # moto -botocore==1.31.80 +botocore==1.32.2 # via # boto3 # moto @@ -121,7 +121,9 @@ comm==0.2.0 # ipykernel # ipywidgets coverage[toml]==7.3.2 - # via pytest-cov + # via + # coverage + # pytest-cov cryptography==41.0.5 # via # azure-identity @@ -135,7 +137,7 @@ cryptography==41.0.5 # snowflake-connector-python # types-pyopenssl # types-redis -dask==2023.10.1 +dask==2023.11.0 # via feast (setup.py) db-dtypes==1.1.1 # via google-cloud-bigquery @@ -177,7 +179,7 @@ fastavro==1.9.0 # via # feast (setup.py) # pandavro -fastjsonschema==2.18.1 +fastjsonschema==2.19.0 # via nbformat filelock==3.13.1 # via @@ -199,7 +201,7 @@ geojson==2.5.0 # via rockset geomet==0.2.1.post1 # via cassandra-driver -google-api-core[grpc]==2.13.0 +google-api-core[grpc]==2.14.0 # via # feast (setup.py) # firebase-admin @@ -211,7 +213,7 @@ google-api-core[grpc]==2.13.0 # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.107.0 +google-api-python-client==2.108.0 # via firebase-admin google-auth==2.23.4 # via @@ -224,7 +226,9 @@ google-auth==2.23.4 google-auth-httplib2==0.1.1 # via google-api-python-client google-cloud-bigquery[pandas]==3.12.0 - # via feast (setup.py) + # via + # feast (setup.py) + # google-cloud-bigquery google-cloud-bigquery-storage==2.22.0 # via feast (setup.py) google-cloud-bigtable==2.21.0 @@ -262,7 +266,7 @@ great-expectations==0.15.50 # via feast (setup.py) greenlet==3.0.1 # via sqlalchemy -grpc-google-iam-v1==0.12.6 +grpc-google-iam-v1==0.12.7 # via google-cloud-bigtable grpcio==1.59.2 # via @@ -298,7 +302,7 @@ hazelcast-python-client==5.3.0 # via feast (setup.py) hiredis==2.2.3 # via feast (setup.py) -httpcore==1.0.1 +httpcore==1.0.2 # via httpx httplib2==0.22.0 # via @@ -368,7 +372,7 @@ jsonpointer==2.4 # via # jsonpatch # jsonschema -jsonschema[format-nongpl]==4.19.2 +jsonschema[format-nongpl]==4.20.0 # via # altair # feast (setup.py) @@ -376,7 +380,7 @@ jsonschema[format-nongpl]==4.19.2 # jupyter-events # jupyterlab-server # nbformat -jsonschema-specifications==2023.7.1 +jsonschema-specifications==2023.11.1 # via jsonschema jupyter-client==8.6.0 # via @@ -396,7 +400,7 @@ jupyter-events==0.9.0 # via jupyter-server jupyter-lsp==2.2.0 # via jupyterlab -jupyter-server==2.10.0 +jupyter-server==2.10.1 # via # jupyter-lsp # jupyterlab @@ -409,7 +413,7 @@ jupyterlab==4.0.8 # via notebook jupyterlab-pygments==0.2.2 # via nbconvert -jupyterlab-server==2.25.0 +jupyterlab-server==2.25.1 # via # jupyterlab # notebook @@ -419,7 +423,7 @@ kubernetes==20.13.0 # via feast (setup.py) locket==1.0.0 # via partd -makefun==1.15.1 +makefun==1.15.2 # via great-expectations markupsafe==2.1.3 # via @@ -446,7 +450,7 @@ mock==2.0.0 # via feast (setup.py) moreorless==0.4.0 # via bowler -moto==4.2.7 +moto==4.2.9 # via feast (setup.py) msal==1.25.0 # via @@ -564,7 +568,7 @@ pre-commit==3.3.1 # via feast (setup.py) prometheus-client==0.18.0 # via jupyter-server -prompt-toolkit==3.0.39 +prompt-toolkit==3.0.41 # via ipython proto-plus==1.22.3 # via @@ -610,7 +614,7 @@ py-cpuinfo==9.0.0 # via pytest-benchmark py4j==0.10.9.7 # via pyspark -pyarrow==10.0.1 +pyarrow==14.0.1 # via # db-dtypes # feast (setup.py) @@ -683,7 +687,7 @@ pytest-ordering==0.6 # via feast (setup.py) pytest-timeout==1.4.2 # via feast (setup.py) -pytest-xdist==3.3.1 +pytest-xdist==3.4.0 # via feast (setup.py) python-dateutil==2.8.2 # via @@ -723,7 +727,7 @@ pyzmq==25.1.1 # jupyter-server redis==4.6.0 # via feast (setup.py) -referencing==0.30.2 +referencing==0.31.0 # via # jsonschema # jsonschema-specifications @@ -751,7 +755,7 @@ requests==2.31.0 # trino requests-oauthlib==1.3.1 # via kubernetes -responses==0.24.0 +responses==0.24.1 # via moto rfc3339-validator==0.1.4 # via @@ -763,7 +767,7 @@ rfc3986-validator==0.1.1 # jupyter-events rockset==2.1.0 # via feast (setup.py) -rpds-py==0.12.0 +rpds-py==0.13.0 # via # jsonschema # referencing @@ -798,8 +802,10 @@ sniffio==1.3.0 # httpx snowballstemmer==2.2.0 # via sphinx -snowflake-connector-python[pandas]==3.4.0 - # via feast (setup.py) +snowflake-connector-python[pandas]==3.5.0 + # via + # feast (setup.py) + # snowflake-connector-python sortedcontainers==2.4.0 # via snowflake-connector-python soupsieve==2.5 @@ -825,8 +831,10 @@ sphinxcontrib-qthelp==1.0.6 sphinxcontrib-serializinghtml==1.1.9 # via sphinx sqlalchemy[mypy]==1.4.50 - # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a36 + # via + # feast (setup.py) + # sqlalchemy +sqlalchemy2-stubs==0.0.2a37 # via sqlalchemy stack-data==0.6.3 # via ipython @@ -836,7 +844,7 @@ tabulate==0.9.0 # via feast (setup.py) tenacity==8.2.3 # via feast (setup.py) -terminado==0.17.1 +terminado==0.18.0 # via # jupyter-server # jupyter-server-terminals @@ -858,7 +866,7 @@ tomli==2.0.1 # pip-tools # pyproject-hooks # pytest -tomlkit==0.12.2 +tomlkit==0.12.3 # via snowflake-connector-python toolz==0.12.0 # via @@ -916,7 +924,7 @@ types-redis==4.6.0.10 # via feast (setup.py) types-requests==2.30.0.0 # via feast (setup.py) -types-setuptools==68.2.0.0 +types-setuptools==68.2.0.1 # via feast (setup.py) types-tabulate==0.9.0.3 # via feast (setup.py) @@ -955,7 +963,9 @@ urllib3==1.26.18 # rockset # snowflake-connector-python uvicorn[standard]==0.24.0.post1 - # via feast (setup.py) + # via + # feast (setup.py) + # uvicorn uvloop==0.19.0 # via uvicorn virtualenv==20.23.0 @@ -966,7 +976,7 @@ volatile==2.1.0 # via bowler watchfiles==0.21.0 # via uvicorn -wcwidth==0.2.9 +wcwidth==0.2.10 # via prompt-toolkit webcolors==1.13 # via jsonschema @@ -987,7 +997,7 @@ wheel==0.41.3 # via pip-tools widgetsnbextension==4.0.9 # via ipywidgets -wrapt==1.15.0 +wrapt==1.16.0 # via testcontainers xmltodict==0.13.0 # via moto diff --git a/sdk/python/requirements/py3.10-requirements.txt b/sdk/python/requirements/py3.10-requirements.txt index 41fee168bf4..0508614aa68 100644 --- a/sdk/python/requirements/py3.10-requirements.txt +++ b/sdk/python/requirements/py3.10-requirements.txt @@ -36,7 +36,7 @@ cloudpickle==3.0.0 # via dask colorama==0.4.6 # via feast (setup.py) -dask==2023.10.1 +dask==2023.11.0 # via feast (setup.py) dill==0.3.7 # via feast (setup.py) @@ -72,7 +72,7 @@ h11==0.14.0 # via # httpcore # uvicorn -httpcore==1.0.1 +httpcore==1.0.2 # via httpx httptools==0.6.1 # via uvicorn @@ -91,9 +91,9 @@ importlib-resources==6.1.1 # via feast (setup.py) jinja2==3.1.2 # via feast (setup.py) -jsonschema==4.19.2 +jsonschema==4.20.0 # via feast (setup.py) -jsonschema-specifications==2023.7.1 +jsonschema-specifications==2023.11.1 # via jsonschema locket==1.0.0 # via partd @@ -103,7 +103,7 @@ mmh3==4.0.1 # via feast (setup.py) moreorless==0.4.0 # via bowler -mypy==1.6.1 +mypy==1.7.0 # via sqlalchemy mypy-extensions==1.0.0 # via mypy @@ -137,7 +137,7 @@ protobuf==4.23.3 # grpcio-tools # mypy-protobuf # proto-plus -pyarrow==11.0.0 +pyarrow==14.0.1 # via feast (setup.py) pydantic==1.10.13 # via @@ -156,13 +156,13 @@ pyyaml==6.0.1 # dask # feast (setup.py) # uvicorn -referencing==0.30.2 +referencing==0.31.0 # via # jsonschema # jsonschema-specifications requests==2.31.0 # via feast (setup.py) -rpds-py==0.12.0 +rpds-py==0.13.0 # via # jsonschema # referencing @@ -175,8 +175,10 @@ sniffio==1.3.0 # anyio # httpx sqlalchemy[mypy]==1.4.50 - # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a36 + # via + # feast (setup.py) + # sqlalchemy +sqlalchemy2-stubs==0.0.2a37 # via sqlalchemy starlette==0.27.0 # via fastapi @@ -205,10 +207,12 @@ typing-extensions==4.8.0 # pydantic # sqlalchemy2-stubs # uvicorn -urllib3==2.0.7 +urllib3==2.1.0 # via requests uvicorn[standard]==0.24.0.post1 - # via feast (setup.py) + # via + # feast (setup.py) + # uvicorn uvloop==0.19.0 # via uvicorn volatile==2.1.0 diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index 855074057a9..8449af824fa 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -63,11 +63,11 @@ black==22.12.0 # via feast (setup.py) bleach==6.1.0 # via nbconvert -boto3==1.28.80 +boto3==1.29.2 # via # feast (setup.py) # moto -botocore==1.31.80 +botocore==1.32.2 # via # boto3 # moto @@ -127,7 +127,9 @@ comm==0.2.0 # ipykernel # ipywidgets coverage[toml]==7.3.2 - # via pytest-cov + # via + # coverage + # pytest-cov cryptography==41.0.5 # via # azure-identity @@ -182,7 +184,7 @@ fastavro==1.9.0 # via # feast (setup.py) # pandavro -fastjsonschema==2.18.1 +fastjsonschema==2.19.0 # via nbformat filelock==3.13.1 # via @@ -204,7 +206,7 @@ geojson==2.5.0 # via rockset geomet==0.2.1.post1 # via cassandra-driver -google-api-core[grpc]==2.13.0 +google-api-core[grpc]==2.14.0 # via # feast (setup.py) # firebase-admin @@ -216,7 +218,7 @@ google-api-core[grpc]==2.13.0 # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.107.0 +google-api-python-client==2.108.0 # via firebase-admin google-auth==2.23.4 # via @@ -229,7 +231,9 @@ google-auth==2.23.4 google-auth-httplib2==0.1.1 # via google-api-python-client google-cloud-bigquery[pandas]==3.12.0 - # via feast (setup.py) + # via + # feast (setup.py) + # google-cloud-bigquery google-cloud-bigquery-storage==2.22.0 # via feast (setup.py) google-cloud-bigtable==2.21.0 @@ -267,7 +271,7 @@ great-expectations==0.15.50 # via feast (setup.py) greenlet==3.0.1 # via sqlalchemy -grpc-google-iam-v1==0.12.6 +grpc-google-iam-v1==0.12.7 # via google-cloud-bigtable grpcio==1.59.2 # via @@ -303,7 +307,7 @@ hazelcast-python-client==5.3.0 # via feast (setup.py) hiredis==2.2.3 # via feast (setup.py) -httpcore==1.0.1 +httpcore==1.0.2 # via httpx httplib2==0.22.0 # via @@ -384,7 +388,7 @@ jsonpointer==2.4 # via # jsonpatch # jsonschema -jsonschema[format-nongpl]==4.19.2 +jsonschema[format-nongpl]==4.20.0 # via # altair # feast (setup.py) @@ -392,7 +396,7 @@ jsonschema[format-nongpl]==4.19.2 # jupyter-events # jupyterlab-server # nbformat -jsonschema-specifications==2023.7.1 +jsonschema-specifications==2023.11.1 # via jsonschema jupyter-client==8.6.0 # via @@ -412,7 +416,7 @@ jupyter-events==0.9.0 # via jupyter-server jupyter-lsp==2.2.0 # via jupyterlab -jupyter-server==2.10.0 +jupyter-server==2.10.1 # via # jupyter-lsp # jupyterlab @@ -425,7 +429,7 @@ jupyterlab==4.0.8 # via notebook jupyterlab-pygments==0.2.2 # via nbconvert -jupyterlab-server==2.25.0 +jupyterlab-server==2.25.1 # via # jupyterlab # notebook @@ -435,7 +439,7 @@ kubernetes==20.13.0 # via feast (setup.py) locket==1.0.0 # via partd -makefun==1.15.1 +makefun==1.15.2 # via great-expectations markupsafe==2.1.3 # via @@ -462,7 +466,7 @@ mock==2.0.0 # via feast (setup.py) moreorless==0.4.0 # via bowler -moto==4.2.7 +moto==4.2.9 # via feast (setup.py) msal==1.25.0 # via @@ -584,7 +588,7 @@ pre-commit==3.3.1 # via feast (setup.py) prometheus-client==0.18.0 # via jupyter-server -prompt-toolkit==3.0.39 +prompt-toolkit==3.0.41 # via ipython proto-plus==1.22.3 # via @@ -630,7 +634,7 @@ py-cpuinfo==9.0.0 # via pytest-benchmark py4j==0.10.9.7 # via pyspark -pyarrow==10.0.1 +pyarrow==14.0.1 # via # db-dtypes # feast (setup.py) @@ -703,7 +707,7 @@ pytest-ordering==0.6 # via feast (setup.py) pytest-timeout==1.4.2 # via feast (setup.py) -pytest-xdist==3.3.1 +pytest-xdist==3.4.0 # via feast (setup.py) python-dateutil==2.8.2 # via @@ -744,7 +748,7 @@ pyzmq==25.1.1 # jupyter-server redis==4.6.0 # via feast (setup.py) -referencing==0.30.2 +referencing==0.31.0 # via # jsonschema # jsonschema-specifications @@ -772,7 +776,7 @@ requests==2.31.0 # trino requests-oauthlib==1.3.1 # via kubernetes -responses==0.24.0 +responses==0.24.1 # via moto rfc3339-validator==0.1.4 # via @@ -784,7 +788,7 @@ rfc3986-validator==0.1.1 # jupyter-events rockset==2.1.0 # via feast (setup.py) -rpds-py==0.12.0 +rpds-py==0.13.0 # via # jsonschema # referencing @@ -821,8 +825,10 @@ sniffio==1.3.0 # httpx snowballstemmer==2.2.0 # via sphinx -snowflake-connector-python[pandas]==3.4.0 - # via feast (setup.py) +snowflake-connector-python[pandas]==3.5.0 + # via + # feast (setup.py) + # snowflake-connector-python sortedcontainers==2.4.0 # via snowflake-connector-python soupsieve==2.5 @@ -842,8 +848,10 @@ sphinxcontrib-qthelp==1.0.3 sphinxcontrib-serializinghtml==1.1.5 # via sphinx sqlalchemy[mypy]==1.4.50 - # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a36 + # via + # feast (setup.py) + # sqlalchemy +sqlalchemy2-stubs==0.0.2a37 # via sqlalchemy stack-data==0.6.3 # via ipython @@ -853,7 +861,7 @@ tabulate==0.9.0 # via feast (setup.py) tenacity==8.2.3 # via feast (setup.py) -terminado==0.17.1 +terminado==0.18.0 # via # jupyter-server # jupyter-server-terminals @@ -875,7 +883,7 @@ tomli==2.0.1 # pip-tools # pyproject-hooks # pytest -tomlkit==0.12.2 +tomlkit==0.12.3 # via snowflake-connector-python toolz==0.12.0 # via @@ -933,7 +941,7 @@ types-redis==4.6.0.10 # via feast (setup.py) types-requests==2.30.0.0 # via feast (setup.py) -types-setuptools==68.2.0.0 +types-setuptools==68.2.0.1 # via feast (setup.py) types-tabulate==0.9.0.3 # via feast (setup.py) @@ -975,7 +983,9 @@ urllib3==1.26.18 # rockset # snowflake-connector-python uvicorn[standard]==0.24.0.post1 - # via feast (setup.py) + # via + # feast (setup.py) + # uvicorn uvloop==0.19.0 # via uvicorn virtualenv==20.23.0 @@ -986,7 +996,7 @@ volatile==2.1.0 # via bowler watchfiles==0.21.0 # via uvicorn -wcwidth==0.2.9 +wcwidth==0.2.10 # via prompt-toolkit webcolors==1.13 # via jsonschema @@ -1007,7 +1017,7 @@ wheel==0.41.3 # via pip-tools widgetsnbextension==4.0.9 # via ipywidgets -wrapt==1.15.0 +wrapt==1.16.0 # via testcontainers xmltodict==0.13.0 # via moto diff --git a/sdk/python/requirements/py3.8-requirements.txt b/sdk/python/requirements/py3.8-requirements.txt index 174dc7d6f52..3f6a15a1ef0 100644 --- a/sdk/python/requirements/py3.8-requirements.txt +++ b/sdk/python/requirements/py3.8-requirements.txt @@ -72,7 +72,7 @@ h11==0.14.0 # via # httpcore # uvicorn -httpcore==1.0.1 +httpcore==1.0.2 # via httpx httptools==0.6.1 # via uvicorn @@ -94,9 +94,9 @@ importlib-resources==6.1.1 # jsonschema-specifications jinja2==3.1.2 # via feast (setup.py) -jsonschema==4.19.2 +jsonschema==4.20.0 # via feast (setup.py) -jsonschema-specifications==2023.7.1 +jsonschema-specifications==2023.11.1 # via jsonschema locket==1.0.0 # via partd @@ -106,7 +106,7 @@ mmh3==4.0.1 # via feast (setup.py) moreorless==0.4.0 # via bowler -mypy==1.6.1 +mypy==1.7.0 # via sqlalchemy mypy-extensions==1.0.0 # via mypy @@ -142,7 +142,7 @@ protobuf==4.23.3 # grpcio-tools # mypy-protobuf # proto-plus -pyarrow==11.0.0 +pyarrow==14.0.1 # via feast (setup.py) pydantic==1.10.13 # via @@ -161,13 +161,13 @@ pyyaml==6.0.1 # dask # feast (setup.py) # uvicorn -referencing==0.30.2 +referencing==0.31.0 # via # jsonschema # jsonschema-specifications requests==2.31.0 # via feast (setup.py) -rpds-py==0.12.0 +rpds-py==0.13.0 # via # jsonschema # referencing @@ -180,8 +180,10 @@ sniffio==1.3.0 # anyio # httpx sqlalchemy[mypy]==1.4.50 - # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a36 + # via + # feast (setup.py) + # sqlalchemy +sqlalchemy2-stubs==0.0.2a37 # via sqlalchemy starlette==0.27.0 # via fastapi @@ -211,10 +213,12 @@ typing-extensions==4.8.0 # sqlalchemy2-stubs # starlette # uvicorn -urllib3==2.0.7 +urllib3==2.1.0 # via requests uvicorn[standard]==0.24.0.post1 - # via feast (setup.py) + # via + # feast (setup.py) + # uvicorn uvloop==0.19.0 # via uvicorn volatile==2.1.0 diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index 4bf35b4adfe..5bc9210fd89 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -57,11 +57,11 @@ black==22.12.0 # via feast (setup.py) bleach==6.1.0 # via nbconvert -boto3==1.28.80 +boto3==1.29.2 # via # feast (setup.py) # moto -botocore==1.31.80 +botocore==1.32.2 # via # boto3 # moto @@ -121,7 +121,9 @@ comm==0.2.0 # ipykernel # ipywidgets coverage[toml]==7.3.2 - # via pytest-cov + # via + # coverage + # pytest-cov cryptography==41.0.5 # via # azure-identity @@ -135,7 +137,7 @@ cryptography==41.0.5 # snowflake-connector-python # types-pyopenssl # types-redis -dask==2023.10.1 +dask==2023.11.0 # via feast (setup.py) db-dtypes==1.1.1 # via google-cloud-bigquery @@ -177,7 +179,7 @@ fastavro==1.9.0 # via # feast (setup.py) # pandavro -fastjsonschema==2.18.1 +fastjsonschema==2.19.0 # via nbformat filelock==3.13.1 # via @@ -199,7 +201,7 @@ geojson==2.5.0 # via rockset geomet==0.2.1.post1 # via cassandra-driver -google-api-core[grpc]==2.13.0 +google-api-core[grpc]==2.14.0 # via # feast (setup.py) # firebase-admin @@ -211,7 +213,7 @@ google-api-core[grpc]==2.13.0 # google-cloud-datastore # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.107.0 +google-api-python-client==2.108.0 # via firebase-admin google-auth==2.23.4 # via @@ -224,7 +226,9 @@ google-auth==2.23.4 google-auth-httplib2==0.1.1 # via google-api-python-client google-cloud-bigquery[pandas]==3.12.0 - # via feast (setup.py) + # via + # feast (setup.py) + # google-cloud-bigquery google-cloud-bigquery-storage==2.22.0 # via feast (setup.py) google-cloud-bigtable==2.21.0 @@ -262,7 +266,7 @@ great-expectations==0.15.50 # via feast (setup.py) greenlet==3.0.1 # via sqlalchemy -grpc-google-iam-v1==0.12.6 +grpc-google-iam-v1==0.12.7 # via google-cloud-bigtable grpcio==1.59.2 # via @@ -298,7 +302,7 @@ hazelcast-python-client==5.3.0 # via feast (setup.py) hiredis==2.2.3 # via feast (setup.py) -httpcore==1.0.1 +httpcore==1.0.2 # via httpx httplib2==0.22.0 # via @@ -375,7 +379,7 @@ jsonpointer==2.4 # via # jsonpatch # jsonschema -jsonschema[format-nongpl]==4.19.2 +jsonschema[format-nongpl]==4.20.0 # via # altair # feast (setup.py) @@ -383,7 +387,7 @@ jsonschema[format-nongpl]==4.19.2 # jupyter-events # jupyterlab-server # nbformat -jsonschema-specifications==2023.7.1 +jsonschema-specifications==2023.11.1 # via jsonschema jupyter-client==8.6.0 # via @@ -403,7 +407,7 @@ jupyter-events==0.9.0 # via jupyter-server jupyter-lsp==2.2.0 # via jupyterlab -jupyter-server==2.10.0 +jupyter-server==2.10.1 # via # jupyter-lsp # jupyterlab @@ -416,7 +420,7 @@ jupyterlab==4.0.8 # via notebook jupyterlab-pygments==0.2.2 # via nbconvert -jupyterlab-server==2.25.0 +jupyterlab-server==2.25.1 # via # jupyterlab # notebook @@ -426,7 +430,7 @@ kubernetes==20.13.0 # via feast (setup.py) locket==1.0.0 # via partd -makefun==1.15.1 +makefun==1.15.2 # via great-expectations markupsafe==2.1.3 # via @@ -453,7 +457,7 @@ mock==2.0.0 # via feast (setup.py) moreorless==0.4.0 # via bowler -moto==4.2.7 +moto==4.2.9 # via feast (setup.py) msal==1.25.0 # via @@ -473,7 +477,7 @@ mypy-extensions==1.0.0 # via # black # mypy -mypy-protobuf==3.1 +mypy-protobuf==3.1.0 # via feast (setup.py) mysqlclient==2.2.0 # via feast (setup.py) @@ -571,7 +575,7 @@ pre-commit==3.3.1 # via feast (setup.py) prometheus-client==0.18.0 # via jupyter-server -prompt-toolkit==3.0.39 +prompt-toolkit==3.0.41 # via ipython proto-plus==1.22.3 # via @@ -617,7 +621,7 @@ py-cpuinfo==9.0.0 # via pytest-benchmark py4j==0.10.9.7 # via pyspark -pyarrow==10.0.1 +pyarrow==14.0.1 # via # db-dtypes # feast (setup.py) @@ -690,7 +694,7 @@ pytest-ordering==0.6 # via feast (setup.py) pytest-timeout==1.4.2 # via feast (setup.py) -pytest-xdist==3.3.1 +pytest-xdist==3.4.0 # via feast (setup.py) python-dateutil==2.8.2 # via @@ -730,7 +734,7 @@ pyzmq==25.1.1 # jupyter-server redis==4.6.0 # via feast (setup.py) -referencing==0.30.2 +referencing==0.31.0 # via # jsonschema # jsonschema-specifications @@ -758,7 +762,7 @@ requests==2.31.0 # trino requests-oauthlib==1.3.1 # via kubernetes -responses==0.24.0 +responses==0.24.1 # via moto rfc3339-validator==0.1.4 # via @@ -770,7 +774,7 @@ rfc3986-validator==0.1.1 # jupyter-events rockset==2.1.0 # via feast (setup.py) -rpds-py==0.12.0 +rpds-py==0.13.0 # via # jsonschema # referencing @@ -807,8 +811,10 @@ sniffio==1.3.0 # httpx snowballstemmer==2.2.0 # via sphinx -snowflake-connector-python[pandas]==3.4.0 - # via feast (setup.py) +snowflake-connector-python[pandas]==3.5.0 + # via + # feast (setup.py) + # snowflake-connector-python sortedcontainers==2.4.0 # via snowflake-connector-python soupsieve==2.5 @@ -834,8 +840,10 @@ sphinxcontrib-qthelp==1.0.6 sphinxcontrib-serializinghtml==1.1.9 # via sphinx sqlalchemy[mypy]==1.4.50 - # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a36 + # via + # feast (setup.py) + # sqlalchemy +sqlalchemy2-stubs==0.0.2a37 # via sqlalchemy stack-data==0.6.3 # via ipython @@ -845,7 +853,7 @@ tabulate==0.9.0 # via feast (setup.py) tenacity==8.2.3 # via feast (setup.py) -terminado==0.17.1 +terminado==0.18.0 # via # jupyter-server # jupyter-server-terminals @@ -867,7 +875,7 @@ tomli==2.0.1 # pip-tools # pyproject-hooks # pytest -tomlkit==0.12.2 +tomlkit==0.12.3 # via snowflake-connector-python toolz==0.12.0 # via @@ -925,7 +933,7 @@ types-redis==4.6.0.10 # via feast (setup.py) types-requests==2.30.0.0 # via feast (setup.py) -types-setuptools==68.2.0.0 +types-setuptools==68.2.0.1 # via feast (setup.py) types-tabulate==0.9.0.3 # via feast (setup.py) @@ -967,7 +975,9 @@ urllib3==1.26.18 # rockset # snowflake-connector-python uvicorn[standard]==0.24.0.post1 - # via feast (setup.py) + # via + # feast (setup.py) + # uvicorn uvloop==0.19.0 # via uvicorn virtualenv==20.23.0 @@ -978,7 +988,7 @@ volatile==2.1.0 # via bowler watchfiles==0.21.0 # via uvicorn -wcwidth==0.2.9 +wcwidth==0.2.10 # via prompt-toolkit webcolors==1.13 # via jsonschema @@ -999,7 +1009,7 @@ wheel==0.41.3 # via pip-tools widgetsnbextension==4.0.9 # via ipywidgets -wrapt==1.15.0 +wrapt==1.16.0 # via testcontainers xmltodict==0.13.0 # via moto diff --git a/sdk/python/requirements/py3.9-requirements.txt b/sdk/python/requirements/py3.9-requirements.txt index 12612c34657..120ecf9eb39 100644 --- a/sdk/python/requirements/py3.9-requirements.txt +++ b/sdk/python/requirements/py3.9-requirements.txt @@ -36,7 +36,7 @@ cloudpickle==3.0.0 # via dask colorama==0.4.6 # via feast (setup.py) -dask==2023.10.1 +dask==2023.11.0 # via feast (setup.py) dill==0.3.7 # via feast (setup.py) @@ -72,7 +72,7 @@ h11==0.14.0 # via # httpcore # uvicorn -httpcore==1.0.1 +httpcore==1.0.2 # via httpx httptools==0.6.1 # via uvicorn @@ -91,9 +91,9 @@ importlib-resources==6.1.1 # via feast (setup.py) jinja2==3.1.2 # via feast (setup.py) -jsonschema==4.19.2 +jsonschema==4.20.0 # via feast (setup.py) -jsonschema-specifications==2023.7.1 +jsonschema-specifications==2023.11.1 # via jsonschema locket==1.0.0 # via partd @@ -103,11 +103,11 @@ mmh3==4.0.1 # via feast (setup.py) moreorless==0.4.0 # via bowler -mypy==1.6.1 +mypy==1.7.0 # via sqlalchemy mypy-extensions==1.0.0 # via mypy -mypy-protobuf==3.1 +mypy-protobuf==3.1.0 # via feast (setup.py) numpy==1.24.4 # via @@ -137,7 +137,7 @@ protobuf==4.23.3 # grpcio-tools # mypy-protobuf # proto-plus -pyarrow==11.0.0 +pyarrow==14.0.1 # via feast (setup.py) pydantic==1.10.13 # via @@ -156,13 +156,13 @@ pyyaml==6.0.1 # dask # feast (setup.py) # uvicorn -referencing==0.30.2 +referencing==0.31.0 # via # jsonschema # jsonschema-specifications requests==2.31.0 # via feast (setup.py) -rpds-py==0.12.0 +rpds-py==0.13.0 # via # jsonschema # referencing @@ -175,8 +175,10 @@ sniffio==1.3.0 # anyio # httpx sqlalchemy[mypy]==1.4.50 - # via feast (setup.py) -sqlalchemy2-stubs==0.0.2a36 + # via + # feast (setup.py) + # sqlalchemy +sqlalchemy2-stubs==0.0.2a37 # via sqlalchemy starlette==0.27.0 # via fastapi @@ -206,10 +208,12 @@ typing-extensions==4.8.0 # sqlalchemy2-stubs # starlette # uvicorn -urllib3==2.0.7 +urllib3==2.1.0 # via requests uvicorn[standard]==0.24.0.post1 - # via feast (setup.py) + # via + # feast (setup.py) + # uvicorn uvloop==0.19.0 # via uvicorn volatile==2.1.0 diff --git a/setup.py b/setup.py index 38b7d295a93..33bf76e1819 100644 --- a/setup.py +++ b/setup.py @@ -60,7 +60,7 @@ # Higher than 4.23.4 seems to cause a seg fault "protobuf<4.23.4,>3.20", "proto-plus>=1.20.0,<2", - "pyarrow>=4,<12", + "pyarrow>=4", "pydantic>=1,<2", "pygments>=2.12.0,<3", "PyYAML>=5.4.0,<7", From 99ded6c0e46e138a5ab3fdea3ddae3e3a654598a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:13:12 -0500 Subject: [PATCH 083/113] chore: Bump follow-redirects from 1.15.0 to 1.15.4 in /sdk/python/feast/ui (#3879) chore: Bump follow-redirects in /sdk/python/feast/ui Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.0 to 1.15.4. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.0...v1.15.4) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/feast/ui/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/feast/ui/yarn.lock b/sdk/python/feast/ui/yarn.lock index 80a16dddcaa..31ee5ae176b 100644 --- a/sdk/python/feast/ui/yarn.lock +++ b/sdk/python/feast/ui/yarn.lock @@ -5485,9 +5485,9 @@ focus-lock@^0.11.2: tslib "^2.0.3" follow-redirects@^1.0.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.0.tgz#06441868281c86d0dda4ad8bdaead2d02dca89d4" - integrity sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ== + version "1.15.4" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" + integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.2" From 288a2675f48d2f5582b179abd40e82e0607b7df8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:13:31 -0500 Subject: [PATCH 084/113] chore: Bump follow-redirects from 1.14.7 to 1.15.4 in /ui (#3878) Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.7 to 1.15.4. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.7...v1.15.4) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- ui/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/yarn.lock b/ui/yarn.lock index 49bff13372a..78fe6863bff 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -5708,9 +5708,9 @@ focus-lock@^0.11.2: tslib "^2.0.3" follow-redirects@^1.0.0: - version "1.14.7" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" - integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== + version "1.15.4" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" + integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.0" From 71cf78bd964e42ba82e8b8a7cff9786ab7a56d5c Mon Sep 17 00:00:00 2001 From: Willem Pienaar <6728866+woop@users.noreply.github.com> Date: Sat, 13 Jan 2024 01:20:26 -0500 Subject: [PATCH 085/113] Update release.yml to latest nodejs Signed-off-by: Attila Toth --- .github/workflows/release.yml | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a01bae40687..b0d3e3cb390 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,8 +36,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v3 with: - node-version: '18.x' - registry-url: 'https://registry.npmjs.org' + node-version: "lts/*" - name: Release (Dry Run) id: get_versions run: | @@ -60,10 +59,10 @@ jobs: NEXT_VERSION: ${{ needs.get_dry_release_versions.outputs.next_version }} steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 with: - node-version: '18.x' - registry-url: 'https://registry.npmjs.org' + node-version: "lts/*" - name: Bump file versions run: python ./infra/scripts/release/bump_file_versions.py ${CURRENT_VERSION} ${NEXT_VERSION} - name: Install yarn dependencies @@ -101,10 +100,10 @@ jobs: NEXT_VERSION: ${{ needs.get_dry_release_versions.outputs.next_version }} steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 with: - node-version: '18.x' - registry-url: 'https://registry.npmjs.org' + node-version: "lts/*" - name: Bump file versions (temporarily for Web UI publish) run: python ./infra/scripts/release/bump_file_versions.py ${CURRENT_VERSION} ${NEXT_VERSION} - name: Install yarn dependencies @@ -139,8 +138,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v3 with: - node-version: '18.x' - registry-url: 'https://registry.npmjs.org' + node-version: "lts/*" - name: Set up Homebrew id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@master From ef5ff9e888ae3090590a378d034e66177b4ebe69 Mon Sep 17 00:00:00 2001 From: feast-ci-bot Date: Sat, 13 Jan 2024 06:33:26 +0000 Subject: [PATCH 086/113] chore(release): release 0.35.0 # [0.35.0](https://github.com/feast-dev/feast/compare/v0.34.0...v0.35.0) (2024-01-13) ### Bug Fixes * Add async refresh to prevent synchronous refresh in main thread ([#3812](https://github.com/feast-dev/feast/issues/3812)) ([9583ed6](https://github.com/feast-dev/feast/commit/9583ed6b4ae8d3b97934bf0c80ecb236ed1e2895)) * Adopt connection pooling for HBase ([#3793](https://github.com/feast-dev/feast/issues/3793)) ([b3852bf](https://github.com/feast-dev/feast/commit/b3852bfb8b27bf07736935f465da3067fcbac0ae)) * Bytewax engine create configmap from object ([#3821](https://github.com/feast-dev/feast/issues/3821)) ([25e9775](https://github.com/feast-dev/feast/commit/25e97756adedfd1227d591ae74bdf60655f9067e)) * Fix warnings from deprecated paths and update default log level ([#3757](https://github.com/feast-dev/feast/issues/3757)) ([68a8737](https://github.com/feast-dev/feast/commit/68a87379c42567f338d86cb2be90520cc6d4bfb6)) * improve parsing bytewax job status ([5983f40](https://github.com/feast-dev/feast/commit/5983f40f8f5df5dbbcd2640f83ef82c19cdb4d19)) * make bytewax settings unexposed ([ae1bb8b](https://github.com/feast-dev/feast/commit/ae1bb8bdd1b9e293809519971935c93c2214d791)) * Make generated temp table name escaped ([#3797](https://github.com/feast-dev/feast/issues/3797)) ([175d796](https://github.com/feast-dev/feast/commit/175d7969b1f75ab797aff9c92a70d845297444ad)) * Pin numpy version to avoid spammy deprecation messages ([774ed33](https://github.com/feast-dev/feast/commit/774ed33a067bf9bf087520325b72f4f4d194106a)) * Redundant feature materialization and premature incremental materialization timestamp updates ([#3789](https://github.com/feast-dev/feast/issues/3789)) ([417b16b](https://github.com/feast-dev/feast/commit/417b16b57af7b38fbd0708b9a0c5d5035ed021fd)), closes [#6](https://github.com/feast-dev/feast/issues/6) [#7](https://github.com/feast-dev/feast/issues/7) * Resolve hbase hotspot issue when materializing ([#3790](https://github.com/feast-dev/feast/issues/3790)) ([7376db8](https://github.com/feast-dev/feast/commit/7376db8dbd1d3168a1262fbbc0ce3899be8d0c34)) * Set keepalives_idle None by default ([#3756](https://github.com/feast-dev/feast/issues/3756)) ([8717e9b](https://github.com/feast-dev/feast/commit/8717e9bf0fd253454982b9c9e9527c4d41906e9c)) * Set upper bound for bigquery client due to its breaking changes ([2151c39](https://github.com/feast-dev/feast/commit/2151c39d1a8d8eba114306411dd4bd91ac0ce3f6)) * UI project cannot handle fallback routes ([#3766](https://github.com/feast-dev/feast/issues/3766)) ([96ece0f](https://github.com/feast-dev/feast/commit/96ece0fe94a07cc6f1dabf5d6c9b061b48b06d67)) * update dependencies versions due to conflicts ([5dc0b24](https://github.com/feast-dev/feast/commit/5dc0b241ec68aa10fd783569bf0ae12c5752f20f)) * Update jackson and remove unnecessary logging ([#3809](https://github.com/feast-dev/feast/issues/3809)) ([018d0ea](https://github.com/feast-dev/feast/commit/018d0eab69dde63266f2c56813045ea5c5523f76)) * upgrade the pyarrow to latest v14.0.1 for CVE-2023-47248. ([052182b](https://github.com/feast-dev/feast/commit/052182bcca046e35456674fc7d524825882f4b35)) ### Features * Add get online feature rpc to gprc server ([#3815](https://github.com/feast-dev/feast/issues/3815)) ([01db8cc](https://github.com/feast-dev/feast/commit/01db8cce6f82d4c6e496041351fb6b56eb2645b0)) * Add materialize and materialize-incremental rest endpoints ([#3761](https://github.com/feast-dev/feast/issues/3761)) ([fa600fe](https://github.com/feast-dev/feast/commit/fa600fe3c4b1d5fdd383a9367511ac5616ee7a32)), closes [#3760](https://github.com/feast-dev/feast/issues/3760) * add redis sentinel support ([3387a15](https://github.com/feast-dev/feast/commit/3387a15d2b7e8dea430a271570be5a19b32bd3fe)) * add redis sentinel support ([4337c89](https://github.com/feast-dev/feast/commit/4337c89083a3cfca21ee1beef473fda13b0e9014)) * add redis sentinel support format lint ([aad8718](https://github.com/feast-dev/feast/commit/aad8718d24d893b3ff8c5864c5b8d210cfcdb22f)) * Add support for `table_create_disposition` in bigquery job for offline store ([#3762](https://github.com/feast-dev/feast/issues/3762)) ([6a728fe](https://github.com/feast-dev/feast/commit/6a728fe66db0286ea10301d1fe693d6dcba4e4f4)) * Add support for in_cluster config and additional labels for bytewax materialization ([#3754](https://github.com/feast-dev/feast/issues/3754)) ([2192e65](https://github.com/feast-dev/feast/commit/2192e6527fa10f1580e4dd8f350e05e45af981b7)) * Apply cache to load proto registry for performance ([#3702](https://github.com/feast-dev/feast/issues/3702)) ([709c709](https://github.com/feast-dev/feast/commit/709c7098dc28a35dd488f5079d3787cf1f74ec03)) * Make bytewax job write as mini-batches ([#3777](https://github.com/feast-dev/feast/issues/3777)) ([9b0e5ce](https://github.com/feast-dev/feast/commit/9b0e5ce2d1b617fcdcf0699c8b0cf8549a5e5ac5)) * Optimize bytewax pod resource with zero-copy ([9cf9d96](https://github.com/feast-dev/feast/commit/9cf9d965a5566a87bb7419f2e8509666076f035f)) * Support GCS filesystem for bytewax engine ([#3774](https://github.com/feast-dev/feast/issues/3774)) ([fb6b807](https://github.com/feast-dev/feast/commit/fb6b807f8b32776d388757ca431d290c03170c66)) Signed-off-by: Attila Toth --- CHANGELOG.md | 37 +++++++++++++++++++ infra/charts/feast-feature-server/Chart.yaml | 2 +- infra/charts/feast-feature-server/README.md | 4 +- infra/charts/feast-feature-server/values.yaml | 2 +- infra/charts/feast/Chart.yaml | 2 +- infra/charts/feast/README.md | 6 +-- .../feast/charts/feature-server/Chart.yaml | 4 +- .../feast/charts/feature-server/README.md | 6 +-- .../feast/charts/feature-server/values.yaml | 2 +- .../charts/transformation-service/Chart.yaml | 4 +- .../charts/transformation-service/README.md | 6 +-- .../charts/transformation-service/values.yaml | 2 +- infra/charts/feast/requirements.yaml | 4 +- java/pom.xml | 2 +- sdk/python/feast/ui/package.json | 2 +- sdk/python/feast/ui/yarn.lock | 8 ++-- ui/package.json | 2 +- 17 files changed, 66 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6e5a430f02..26b8baa963e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,42 @@ # Changelog +# [0.35.0](https://github.com/feast-dev/feast/compare/v0.34.0...v0.35.0) (2024-01-13) + + +### Bug Fixes + +* Add async refresh to prevent synchronous refresh in main thread ([#3812](https://github.com/feast-dev/feast/issues/3812)) ([9583ed6](https://github.com/feast-dev/feast/commit/9583ed6b4ae8d3b97934bf0c80ecb236ed1e2895)) +* Adopt connection pooling for HBase ([#3793](https://github.com/feast-dev/feast/issues/3793)) ([b3852bf](https://github.com/feast-dev/feast/commit/b3852bfb8b27bf07736935f465da3067fcbac0ae)) +* Bytewax engine create configmap from object ([#3821](https://github.com/feast-dev/feast/issues/3821)) ([25e9775](https://github.com/feast-dev/feast/commit/25e97756adedfd1227d591ae74bdf60655f9067e)) +* Fix warnings from deprecated paths and update default log level ([#3757](https://github.com/feast-dev/feast/issues/3757)) ([68a8737](https://github.com/feast-dev/feast/commit/68a87379c42567f338d86cb2be90520cc6d4bfb6)) +* improve parsing bytewax job status ([5983f40](https://github.com/feast-dev/feast/commit/5983f40f8f5df5dbbcd2640f83ef82c19cdb4d19)) +* make bytewax settings unexposed ([ae1bb8b](https://github.com/feast-dev/feast/commit/ae1bb8bdd1b9e293809519971935c93c2214d791)) +* Make generated temp table name escaped ([#3797](https://github.com/feast-dev/feast/issues/3797)) ([175d796](https://github.com/feast-dev/feast/commit/175d7969b1f75ab797aff9c92a70d845297444ad)) +* Pin numpy version to avoid spammy deprecation messages ([774ed33](https://github.com/feast-dev/feast/commit/774ed33a067bf9bf087520325b72f4f4d194106a)) +* Redundant feature materialization and premature incremental materialization timestamp updates ([#3789](https://github.com/feast-dev/feast/issues/3789)) ([417b16b](https://github.com/feast-dev/feast/commit/417b16b57af7b38fbd0708b9a0c5d5035ed021fd)), closes [#6](https://github.com/feast-dev/feast/issues/6) [#7](https://github.com/feast-dev/feast/issues/7) +* Resolve hbase hotspot issue when materializing ([#3790](https://github.com/feast-dev/feast/issues/3790)) ([7376db8](https://github.com/feast-dev/feast/commit/7376db8dbd1d3168a1262fbbc0ce3899be8d0c34)) +* Set keepalives_idle None by default ([#3756](https://github.com/feast-dev/feast/issues/3756)) ([8717e9b](https://github.com/feast-dev/feast/commit/8717e9bf0fd253454982b9c9e9527c4d41906e9c)) +* Set upper bound for bigquery client due to its breaking changes ([2151c39](https://github.com/feast-dev/feast/commit/2151c39d1a8d8eba114306411dd4bd91ac0ce3f6)) +* UI project cannot handle fallback routes ([#3766](https://github.com/feast-dev/feast/issues/3766)) ([96ece0f](https://github.com/feast-dev/feast/commit/96ece0fe94a07cc6f1dabf5d6c9b061b48b06d67)) +* update dependencies versions due to conflicts ([5dc0b24](https://github.com/feast-dev/feast/commit/5dc0b241ec68aa10fd783569bf0ae12c5752f20f)) +* Update jackson and remove unnecessary logging ([#3809](https://github.com/feast-dev/feast/issues/3809)) ([018d0ea](https://github.com/feast-dev/feast/commit/018d0eab69dde63266f2c56813045ea5c5523f76)) +* upgrade the pyarrow to latest v14.0.1 for CVE-2023-47248. ([052182b](https://github.com/feast-dev/feast/commit/052182bcca046e35456674fc7d524825882f4b35)) + + +### Features + +* Add get online feature rpc to gprc server ([#3815](https://github.com/feast-dev/feast/issues/3815)) ([01db8cc](https://github.com/feast-dev/feast/commit/01db8cce6f82d4c6e496041351fb6b56eb2645b0)) +* Add materialize and materialize-incremental rest endpoints ([#3761](https://github.com/feast-dev/feast/issues/3761)) ([fa600fe](https://github.com/feast-dev/feast/commit/fa600fe3c4b1d5fdd383a9367511ac5616ee7a32)), closes [#3760](https://github.com/feast-dev/feast/issues/3760) +* add redis sentinel support ([3387a15](https://github.com/feast-dev/feast/commit/3387a15d2b7e8dea430a271570be5a19b32bd3fe)) +* add redis sentinel support ([4337c89](https://github.com/feast-dev/feast/commit/4337c89083a3cfca21ee1beef473fda13b0e9014)) +* add redis sentinel support format lint ([aad8718](https://github.com/feast-dev/feast/commit/aad8718d24d893b3ff8c5864c5b8d210cfcdb22f)) +* Add support for `table_create_disposition` in bigquery job for offline store ([#3762](https://github.com/feast-dev/feast/issues/3762)) ([6a728fe](https://github.com/feast-dev/feast/commit/6a728fe66db0286ea10301d1fe693d6dcba4e4f4)) +* Add support for in_cluster config and additional labels for bytewax materialization ([#3754](https://github.com/feast-dev/feast/issues/3754)) ([2192e65](https://github.com/feast-dev/feast/commit/2192e6527fa10f1580e4dd8f350e05e45af981b7)) +* Apply cache to load proto registry for performance ([#3702](https://github.com/feast-dev/feast/issues/3702)) ([709c709](https://github.com/feast-dev/feast/commit/709c7098dc28a35dd488f5079d3787cf1f74ec03)) +* Make bytewax job write as mini-batches ([#3777](https://github.com/feast-dev/feast/issues/3777)) ([9b0e5ce](https://github.com/feast-dev/feast/commit/9b0e5ce2d1b617fcdcf0699c8b0cf8549a5e5ac5)) +* Optimize bytewax pod resource with zero-copy ([9cf9d96](https://github.com/feast-dev/feast/commit/9cf9d965a5566a87bb7419f2e8509666076f035f)) +* Support GCS filesystem for bytewax engine ([#3774](https://github.com/feast-dev/feast/issues/3774)) ([fb6b807](https://github.com/feast-dev/feast/commit/fb6b807f8b32776d388757ca431d290c03170c66)) + # [0.34.0](https://github.com/feast-dev/feast/compare/v0.33.0...v0.34.0) (2023-09-07) diff --git a/infra/charts/feast-feature-server/Chart.yaml b/infra/charts/feast-feature-server/Chart.yaml index 6631d377844..6111639b684 100644 --- a/infra/charts/feast-feature-server/Chart.yaml +++ b/infra/charts/feast-feature-server/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: feast-feature-server description: Feast Feature Server in Go or Python type: application -version: 0.34.0 +version: 0.35.0 keywords: - machine learning - big data diff --git a/infra/charts/feast-feature-server/README.md b/infra/charts/feast-feature-server/README.md index ad88d082178..2467b60e1e8 100644 --- a/infra/charts/feast-feature-server/README.md +++ b/infra/charts/feast-feature-server/README.md @@ -1,6 +1,6 @@ # Feast Python / Go Feature Server Helm Charts -Current chart version is `0.34.0` +Current chart version is `0.35.0` ## Installation @@ -30,7 +30,7 @@ See [here](https://github.com/feast-dev/feast/tree/master/examples/python-helm-d | fullnameOverride | string | `""` | | | image.pullPolicy | string | `"IfNotPresent"` | | | image.repository | string | `"feastdev/feature-server"` | Docker image for Feature Server repository | -| image.tag | string | `"0.34.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | +| image.tag | string | `"0.35.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | | imagePullSecrets | list | `[]` | | | livenessProbe.initialDelaySeconds | int | `30` | | | livenessProbe.periodSeconds | int | `30` | | diff --git a/infra/charts/feast-feature-server/values.yaml b/infra/charts/feast-feature-server/values.yaml index d46f1b685b3..2383d6fa9fd 100644 --- a/infra/charts/feast-feature-server/values.yaml +++ b/infra/charts/feast-feature-server/values.yaml @@ -9,7 +9,7 @@ image: repository: feastdev/feature-server pullPolicy: IfNotPresent # image.tag -- The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) - tag: 0.34.0 + tag: 0.35.0 imagePullSecrets: [] nameOverride: "" diff --git a/infra/charts/feast/Chart.yaml b/infra/charts/feast/Chart.yaml index e0f530e05ee..c53b73848c4 100644 --- a/infra/charts/feast/Chart.yaml +++ b/infra/charts/feast/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 description: Feature store for machine learning name: feast -version: 0.34.0 +version: 0.35.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index fff6d0261bd..d8d4a3d376d 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -8,7 +8,7 @@ This repo contains Helm charts for Feast Java components that are being installe ## Chart: Feast -Feature store for machine learning Current chart version is `0.34.0` +Feature store for machine learning Current chart version is `0.35.0` ## Installation @@ -65,8 +65,8 @@ See [here](https://github.com/feast-dev/feast/tree/master/examples/java-demo) fo | Repository | Name | Version | |------------|------|---------| | https://charts.helm.sh/stable | redis | 10.5.6 | -| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.34.0 | -| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.34.0 | +| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.35.0 | +| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.35.0 | ## Values diff --git a/infra/charts/feast/charts/feature-server/Chart.yaml b/infra/charts/feast/charts/feature-server/Chart.yaml index bfb33b6140f..122c80f9fd7 100644 --- a/infra/charts/feast/charts/feature-server/Chart.yaml +++ b/infra/charts/feast/charts/feature-server/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 description: "Feast Feature Server: Online feature serving service for Feast" name: feature-server -version: 0.34.0 -appVersion: v0.34.0 +version: 0.35.0 +appVersion: v0.35.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/charts/feature-server/README.md b/infra/charts/feast/charts/feature-server/README.md index f768a46cd53..514fcc57278 100644 --- a/infra/charts/feast/charts/feature-server/README.md +++ b/infra/charts/feast/charts/feature-server/README.md @@ -1,6 +1,6 @@ # feature-server -![Version: 0.34.0](https://img.shields.io/badge/Version-0.34.0-informational?style=flat-square) ![AppVersion: v0.34.0](https://img.shields.io/badge/AppVersion-v0.34.0-informational?style=flat-square) +![Version: 0.35.0](https://img.shields.io/badge/Version-0.35.0-informational?style=flat-square) ![AppVersion: v0.35.0](https://img.shields.io/badge/AppVersion-v0.35.0-informational?style=flat-square) Feast Feature Server: Online feature serving service for Feast @@ -17,7 +17,7 @@ Feast Feature Server: Online feature serving service for Feast | envOverrides | object | `{}` | Extra environment variables to set | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"feastdev/feature-server-java"` | Docker image for Feature Server repository | -| image.tag | string | `"0.34.0"` | Image tag | +| image.tag | string | `"0.35.0"` | Image tag | | ingress.grpc.annotations | object | `{}` | Extra annotations for the ingress | | ingress.grpc.auth.enabled | bool | `false` | Flag to enable auth | | ingress.grpc.class | string | `"nginx"` | Which ingress controller to use | @@ -64,4 +64,4 @@ Feast Feature Server: Online feature serving service for Feast | transformationService.port | int | `6566` | | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) +Autogenerated from chart metadata using [helm-docs v1.12.0](https://github.com/norwoodj/helm-docs/releases/v1.12.0) diff --git a/infra/charts/feast/charts/feature-server/values.yaml b/infra/charts/feast/charts/feature-server/values.yaml index 24b8da1e39a..a14cc2d28f3 100644 --- a/infra/charts/feast/charts/feature-server/values.yaml +++ b/infra/charts/feast/charts/feature-server/values.yaml @@ -5,7 +5,7 @@ image: # image.repository -- Docker image for Feature Server repository repository: feastdev/feature-server-java # image.tag -- Image tag - tag: 0.34.0 + tag: 0.35.0 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/charts/transformation-service/Chart.yaml b/infra/charts/feast/charts/transformation-service/Chart.yaml index 5d8f157a48f..852045f52b5 100644 --- a/infra/charts/feast/charts/transformation-service/Chart.yaml +++ b/infra/charts/feast/charts/transformation-service/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 description: "Transformation service: to compute on-demand features" name: transformation-service -version: 0.34.0 -appVersion: v0.34.0 +version: 0.35.0 +appVersion: v0.35.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/charts/transformation-service/README.md b/infra/charts/feast/charts/transformation-service/README.md index cf8c7eaae87..758620d56a5 100644 --- a/infra/charts/feast/charts/transformation-service/README.md +++ b/infra/charts/feast/charts/transformation-service/README.md @@ -1,6 +1,6 @@ # transformation-service -![Version: 0.34.0](https://img.shields.io/badge/Version-0.34.0-informational?style=flat-square) ![AppVersion: v0.34.0](https://img.shields.io/badge/AppVersion-v0.34.0-informational?style=flat-square) +![Version: 0.35.0](https://img.shields.io/badge/Version-0.35.0-informational?style=flat-square) ![AppVersion: v0.35.0](https://img.shields.io/badge/AppVersion-v0.35.0-informational?style=flat-square) Transformation service: to compute on-demand features @@ -13,7 +13,7 @@ Transformation service: to compute on-demand features | envOverrides | object | `{}` | Extra environment variables to set | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"feastdev/feature-transformation-server"` | Docker image for Transformation Server repository | -| image.tag | string | `"0.34.0"` | Image tag | +| image.tag | string | `"0.35.0"` | Image tag | | nodeSelector | object | `{}` | Node labels for pod assignment | | podLabels | object | `{}` | Labels to be added to Feast Serving pods | | replicaCount | int | `1` | Number of pods that will be created | @@ -25,4 +25,4 @@ Transformation service: to compute on-demand features | service.type | string | `"ClusterIP"` | Kubernetes service type | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) +Autogenerated from chart metadata using [helm-docs v1.12.0](https://github.com/norwoodj/helm-docs/releases/v1.12.0) diff --git a/infra/charts/feast/charts/transformation-service/values.yaml b/infra/charts/feast/charts/transformation-service/values.yaml index 6af9e569ea9..e45ef47288d 100644 --- a/infra/charts/feast/charts/transformation-service/values.yaml +++ b/infra/charts/feast/charts/transformation-service/values.yaml @@ -5,7 +5,7 @@ image: # image.repository -- Docker image for Transformation Server repository repository: feastdev/feature-transformation-server # image.tag -- Image tag - tag: 0.34.0 + tag: 0.35.0 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/requirements.yaml b/infra/charts/feast/requirements.yaml index b3236b03228..ec098f2f7b9 100644 --- a/infra/charts/feast/requirements.yaml +++ b/infra/charts/feast/requirements.yaml @@ -1,12 +1,12 @@ dependencies: - name: feature-server alias: feature-server - version: 0.34.0 + version: 0.35.0 condition: feature-server.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: transformation-service alias: transformation-service - version: 0.34.0 + version: 0.35.0 condition: transformation-service.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: redis diff --git a/java/pom.xml b/java/pom.xml index 3a94e5f19c3..59c67337842 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -35,7 +35,7 @@ - 0.34.0 + 0.35.0 https://github.com/feast-dev/feast UTF-8 diff --git a/sdk/python/feast/ui/package.json b/sdk/python/feast/ui/package.json index 80956440abf..1d2951cf57f 100644 --- a/sdk/python/feast/ui/package.json +++ b/sdk/python/feast/ui/package.json @@ -6,7 +6,7 @@ "@elastic/datemath": "^5.0.3", "@elastic/eui": "^55.0.1", "@emotion/react": "^11.9.0", - "@feast-dev/feast-ui": "0.34.0", + "@feast-dev/feast-ui": "0.35.0", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.2.0", "@testing-library/user-event": "^13.5.0", diff --git a/sdk/python/feast/ui/yarn.lock b/sdk/python/feast/ui/yarn.lock index 31ee5ae176b..4d6f690b949 100644 --- a/sdk/python/feast/ui/yarn.lock +++ b/sdk/python/feast/ui/yarn.lock @@ -1451,10 +1451,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@feast-dev/feast-ui@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@feast-dev/feast-ui/-/feast-ui-0.34.0.tgz#21799c119da936814ff47e1d1d297258ecfda098" - integrity sha512-ErrnmaFPMgnmnTpBpn7T0oiC3cA+atE5yKBmoMFXBsK6aplu18aF53QBX4JJFKMKF+A2BcO37veeXm1k01SJQQ== +"@feast-dev/feast-ui@0.35.0": + version "0.35.0" + resolved "https://registry.yarnpkg.com/@feast-dev/feast-ui/-/feast-ui-0.35.0.tgz#f28eb82ae4855673230f14e3740a7786f545fdd7" + integrity sha512-t0Rd2TWUMim6ITfVVlQU8aBZboLvxla6Z7udGW+tQ3UUGcq1VbM6/y+GobuYQfbdHHeF2GmlYqp6zw5DuoIM+Q== dependencies: "@elastic/datemath" "^5.0.3" "@elastic/eui" "^55.0.1" diff --git a/ui/package.json b/ui/package.json index dc16a1e7a6a..c826737cf63 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "@feast-dev/feast-ui", - "version": "0.34.0", + "version": "0.35.0", "private": false, "files": [ "dist" From 6515c98460b29efcafa1bd36ee25248c34dbc073 Mon Sep 17 00:00:00 2001 From: Rob Howley Date: Mon, 15 Jan 2024 14:59:14 -0500 Subject: [PATCH 087/113] feat: Add python bytes to array type conversion support proto (#3874) * feat: add redis sentinel support format lint Signed-off-by: snowron Signed-off-by: Rob Howley * chore: Bump pyarrow Bumps [pyarrow](https://github.com/apache/arrow) from 6.0.0 to 14.0.1. - [Commits](https://github.com/apache/arrow/compare/go/arrow/v6.0.0...apache-arrow-14.0.1) --- updated-dependencies: - dependency-name: pyarrow dependency-type: direct:production ... Signed-off-by: dependabot[bot] Signed-off-by: Rob Howley * fix: upgrade the pyarrow to latest v14.0.1 for CVE-2023-47248. Signed-off-by: Shuchu Han Signed-off-by: Rob Howley * feat: add bytes to array type conversion in python -> proto Signed-off-by: Rob Howley * ignore type like in other proto val assignments Signed-off-by: Rob Howley * run black Signed-off-by: Rob Howley * floats can also appear as ints Signed-off-by: Rob Howley --------- Signed-off-by: snowron Signed-off-by: Rob Howley Signed-off-by: dependabot[bot] Signed-off-by: Shuchu Han Co-authored-by: snowron Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Shuchu Han Co-authored-by: Rob Howley Signed-off-by: Attila Toth --- sdk/python/feast/type_map.py | 17 +++++++++++++- sdk/python/tests/unit/test_type_map.py | 32 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/sdk/python/feast/type_map.py b/sdk/python/feast/type_map.py index cdb65f886e2..9dbbb5a64ce 100644 --- a/sdk/python/feast/type_map.py +++ b/sdk/python/feast/type_map.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json from collections import defaultdict from datetime import datetime, timezone from typing import ( @@ -297,7 +298,7 @@ def _type_err(item, dtype): None, ), ValueType.FLOAT: ("float_val", lambda x: float(x), None), - ValueType.DOUBLE: ("double_val", lambda x: x, {float, np.float64}), + ValueType.DOUBLE: ("double_val", lambda x: x, {float, np.float64, int, np.int_}), ValueType.STRING: ("string_val", lambda x: str(x), None), ValueType.BYTES: ("bytes_val", lambda x: x, {bytes}), ValueType.BOOL: ("bool_val", lambda x: x, {bool, np.bool_, int, np.int_}), @@ -353,6 +354,19 @@ def _python_value_to_proto_value( feast_value_type ] + # Bytes to array type conversion + if isinstance(sample, (bytes, bytearray)): + # Bytes of an array containing elements of bytes not supported + if feast_value_type == ValueType.BYTES_LIST: + raise _type_err(sample, ValueType.BYTES_LIST) + + json_value = json.loads(sample) + if isinstance(json_value, list): + if feast_value_type == ValueType.BOOL_LIST: + json_value = [bool(item) for item in json_value] + return [ProtoValue(**{field_name: proto_type(val=json_value)})] # type: ignore + raise _type_err(sample, valid_types[0]) + if sample is not None and not all( type(item) in valid_types for item in sample ): @@ -631,6 +645,7 @@ def redshift_to_feast_value_type(redshift_type_as_str: str) -> ValueType: "varchar": ValueType.STRING, "timestamp": ValueType.UNIX_TIMESTAMP, "timestamptz": ValueType.UNIX_TIMESTAMP, + "super": ValueType.BYTES, # skip date, geometry, hllsketch, time, timetz } diff --git a/sdk/python/tests/unit/test_type_map.py b/sdk/python/tests/unit/test_type_map.py index 78ff15fe931..9b21900e6d7 100644 --- a/sdk/python/tests/unit/test_type_map.py +++ b/sdk/python/tests/unit/test_type_map.py @@ -48,3 +48,35 @@ def test_python_values_to_proto_values_bool(values): converted = feast_value_type_to_python_type(protos[0]) assert converted is bool(values[0]) + + +@pytest.mark.parametrize( + "values, value_type, expected", + ( + (np.array([b"[1,2,3]"]), ValueType.INT64_LIST, [1, 2, 3]), + (np.array([b"[1,2,3]"]), ValueType.INT32_LIST, [1, 2, 3]), + (np.array([b"[1.5,2.5,3.5]"]), ValueType.FLOAT_LIST, [1.5, 2.5, 3.5]), + (np.array([b"[1.5,2.5,3.5]"]), ValueType.DOUBLE_LIST, [1.5, 2.5, 3.5]), + (np.array([b'["a","b","c"]']), ValueType.STRING_LIST, ["a", "b", "c"]), + (np.array([b"[true,false]"]), ValueType.BOOL_LIST, [True, False]), + (np.array([b"[1,0]"]), ValueType.BOOL_LIST, [True, False]), + (np.array([None]), ValueType.STRING_LIST, None), + ([b"[1,2,3]"], ValueType.INT64_LIST, [1, 2, 3]), + ([b"[1,2,3]"], ValueType.INT32_LIST, [1, 2, 3]), + ([b"[1.5,2.5,3.5]"], ValueType.FLOAT_LIST, [1.5, 2.5, 3.5]), + ([b"[1.5,2.5,3.5]"], ValueType.DOUBLE_LIST, [1.5, 2.5, 3.5]), + ([b'["a","b","c"]'], ValueType.STRING_LIST, ["a", "b", "c"]), + ([b"[true,false]"], ValueType.BOOL_LIST, [True, False]), + ([b"[1,0]"], ValueType.BOOL_LIST, [True, False]), + ([None], ValueType.STRING_LIST, None), + ), +) +def test_python_values_to_proto_values_bytes_to_list(values, value_type, expected): + protos = python_values_to_proto_values(values, value_type) + converted = feast_value_type_to_python_type(protos[0]) + assert converted == expected + + +def test_python_values_to_proto_values_bytes_to_list_not_supported(): + with pytest.raises(TypeError): + _ = python_values_to_proto_values([b"[]"], ValueType.BYTES_LIST) From 97425b870e105fc32b3bdcadd844bb76e8ec28d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 15:44:31 -0500 Subject: [PATCH 088/113] chore: Bump jupyter-server from 2.10.1 to 2.11.2 in /sdk/python/requirements (#3858) chore: Bump jupyter-server in /sdk/python/requirements Bumps [jupyter-server](https://github.com/jupyter-server/jupyter_server) from 2.10.1 to 2.11.2. - [Release notes](https://github.com/jupyter-server/jupyter_server/releases) - [Changelog](https://github.com/jupyter-server/jupyter_server/blob/main/CHANGELOG.md) - [Commits](https://github.com/jupyter-server/jupyter_server/compare/v2.10.1...v2.11.2) --- updated-dependencies: - dependency-name: jupyter-server dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/requirements/py3.10-ci-requirements.txt | 2 +- sdk/python/requirements/py3.8-ci-requirements.txt | 2 +- sdk/python/requirements/py3.9-ci-requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index 2cbfa6cbc96..5eb5cb294d1 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -400,7 +400,7 @@ jupyter-events==0.9.0 # via jupyter-server jupyter-lsp==2.2.0 # via jupyterlab -jupyter-server==2.10.1 +jupyter-server==2.11.2 # via # jupyter-lsp # jupyterlab diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index 8449af824fa..911ef15e394 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -416,7 +416,7 @@ jupyter-events==0.9.0 # via jupyter-server jupyter-lsp==2.2.0 # via jupyterlab -jupyter-server==2.10.1 +jupyter-server==2.11.2 # via # jupyter-lsp # jupyterlab diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index 5bc9210fd89..c7ed9f021e6 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -407,7 +407,7 @@ jupyter-events==0.9.0 # via jupyter-server jupyter-lsp==2.2.0 # via jupyterlab -jupyter-server==2.10.1 +jupyter-server==2.11.2 # via # jupyter-lsp # jupyterlab From c30f19044c3e3b401a9351f9ff855d8d3142e98b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 10:38:29 -0500 Subject: [PATCH 089/113] chore: Bump jinja2 from 3.1.2 to 3.1.3 in /sdk/python/requirements (#3882) Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.3) --- updated-dependencies: - dependency-name: jinja2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/requirements/py3.10-ci-requirements.txt | 2 +- sdk/python/requirements/py3.10-requirements.txt | 2 +- sdk/python/requirements/py3.8-ci-requirements.txt | 2 +- sdk/python/requirements/py3.8-requirements.txt | 2 +- sdk/python/requirements/py3.9-ci-requirements.txt | 2 +- sdk/python/requirements/py3.9-requirements.txt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index 5eb5cb294d1..362b38ea474 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -349,7 +349,7 @@ isort==5.12.0 # via feast (setup.py) jedi==0.19.1 # via ipython -jinja2==3.1.2 +jinja2==3.1.3 # via # altair # feast (setup.py) diff --git a/sdk/python/requirements/py3.10-requirements.txt b/sdk/python/requirements/py3.10-requirements.txt index 0508614aa68..18486d7fa9a 100644 --- a/sdk/python/requirements/py3.10-requirements.txt +++ b/sdk/python/requirements/py3.10-requirements.txt @@ -89,7 +89,7 @@ importlib-metadata==6.8.0 # feast (setup.py) importlib-resources==6.1.1 # via feast (setup.py) -jinja2==3.1.2 +jinja2==3.1.3 # via feast (setup.py) jsonschema==4.20.0 # via feast (setup.py) diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index 911ef15e394..e219935b01e 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -365,7 +365,7 @@ isort==5.12.0 # via feast (setup.py) jedi==0.19.1 # via ipython -jinja2==3.1.2 +jinja2==3.1.3 # via # altair # feast (setup.py) diff --git a/sdk/python/requirements/py3.8-requirements.txt b/sdk/python/requirements/py3.8-requirements.txt index 3f6a15a1ef0..c180c50c81e 100644 --- a/sdk/python/requirements/py3.8-requirements.txt +++ b/sdk/python/requirements/py3.8-requirements.txt @@ -92,7 +92,7 @@ importlib-resources==6.1.1 # feast (setup.py) # jsonschema # jsonschema-specifications -jinja2==3.1.2 +jinja2==3.1.3 # via feast (setup.py) jsonschema==4.20.0 # via feast (setup.py) diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index c7ed9f021e6..3acecd892c0 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -356,7 +356,7 @@ isort==5.12.0 # via feast (setup.py) jedi==0.19.1 # via ipython -jinja2==3.1.2 +jinja2==3.1.3 # via # altair # feast (setup.py) diff --git a/sdk/python/requirements/py3.9-requirements.txt b/sdk/python/requirements/py3.9-requirements.txt index 120ecf9eb39..3b6f88b4e2a 100644 --- a/sdk/python/requirements/py3.9-requirements.txt +++ b/sdk/python/requirements/py3.9-requirements.txt @@ -89,7 +89,7 @@ importlib-metadata==6.8.0 # feast (setup.py) importlib-resources==6.1.1 # via feast (setup.py) -jinja2==3.1.2 +jinja2==3.1.3 # via feast (setup.py) jsonschema==4.20.0 # via feast (setup.py) From 7ea9cb74cb86b0506ee6902ca154170477633504 Mon Sep 17 00:00:00 2001 From: Willem Pienaar <6728866+woop@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:57:03 -0500 Subject: [PATCH 090/113] Move maintainers to emeritus (#3888) Signed-off-by: Attila Toth --- community/maintainers.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/community/maintainers.md b/community/maintainers.md index e66dbeb7629..8aca48fd0db 100644 --- a/community/maintainers.md +++ b/community/maintainers.md @@ -9,9 +9,6 @@ In alphabetical order | Name | GitHub Username | Email | Organization | | -------------- | ---------------- |-----------------------------| ------------------ | | Achal Shah | `achals` | achals@gmail.com | Tecton | -| Felix Wang | `felixwang9817` | wangfelix98@gmail.com | Tecton | -| Kevin Zhang | `kevjumba` | kevin.zhang.13499@gmail.com | Tecton | -| Miles Adkins | `sfc-gh-madkins` | miles.adkins@snowflake.com | Snowflake | | Willem Pienaar | `woop` | will.pienaar@gmail.com | Tecton | | Zhiling Chen | `zhilingc` | chnzhlng@gmail.com | GetGround | @@ -29,3 +26,6 @@ In alphabetical order | Danny Chiao | adchia | danny@tecton.ai | Tecton | | David Liu | mavysavydav | davidyliuliu@gmail.com | Twitter | | Matt Delacour | MattDelac | mdelacour@hey.com | Shopify | +| Miles Adkins | sfc-gh-madkins | miles.adkins@snowflake.com | Snowflake | +| Felix Wang | `felixwang9817` | wangfelix98@gmail.com | Tecton | +| Kevin Zhang | `kevjumba` | kevin.zhang.13499@gmail.com | Tecton | From 86de72568ef3204481603e903708d08412c29ab7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 22:16:36 -0500 Subject: [PATCH 091/113] chore: Bump jupyter-lsp from 2.2.0 to 2.2.2 in /sdk/python/requirements (#3892) Bumps [jupyter-lsp](https://github.com/jupyter-lsp/jupyterlab-lsp) from 2.2.0 to 2.2.2. - [Release notes](https://github.com/jupyter-lsp/jupyterlab-lsp/releases) - [Changelog](https://github.com/jupyter-lsp/jupyterlab-lsp/blob/main/CHANGELOG.md) - [Commits](https://github.com/jupyter-lsp/jupyterlab-lsp/commits) --- updated-dependencies: - dependency-name: jupyter-lsp dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/requirements/py3.10-ci-requirements.txt | 2 +- sdk/python/requirements/py3.8-ci-requirements.txt | 2 +- sdk/python/requirements/py3.9-ci-requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index 362b38ea474..ddc4d15ac4d 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -398,7 +398,7 @@ jupyter-core==5.5.0 # nbformat jupyter-events==0.9.0 # via jupyter-server -jupyter-lsp==2.2.0 +jupyter-lsp==2.2.2 # via jupyterlab jupyter-server==2.11.2 # via diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index e219935b01e..d8e948ab7cf 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -414,7 +414,7 @@ jupyter-core==5.5.0 # nbformat jupyter-events==0.9.0 # via jupyter-server -jupyter-lsp==2.2.0 +jupyter-lsp==2.2.2 # via jupyterlab jupyter-server==2.11.2 # via diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index 3acecd892c0..fd79e7cf4a0 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -405,7 +405,7 @@ jupyter-core==5.5.0 # nbformat jupyter-events==0.9.0 # via jupyter-server -jupyter-lsp==2.2.0 +jupyter-lsp==2.2.2 # via jupyterlab jupyter-server==2.11.2 # via From 7b21c84c282034cc56b4bd74a9e53f61ffcd53ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 22:48:50 -0500 Subject: [PATCH 092/113] chore: Bump cryptography from 41.0.5 to 41.0.6 in /sdk/python/requirements (#3845) chore: Bump cryptography in /sdk/python/requirements Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.5 to 41.0.6. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.5...41.0.6) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/requirements/py3.10-ci-requirements.txt | 2 +- sdk/python/requirements/py3.8-ci-requirements.txt | 2 +- sdk/python/requirements/py3.9-ci-requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index ddc4d15ac4d..5e407c1a991 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -124,7 +124,7 @@ coverage[toml]==7.3.2 # via # coverage # pytest-cov -cryptography==41.0.5 +cryptography==41.0.6 # via # azure-identity # azure-storage-blob diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index d8e948ab7cf..02eaf6dc307 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -130,7 +130,7 @@ coverage[toml]==7.3.2 # via # coverage # pytest-cov -cryptography==41.0.5 +cryptography==41.0.6 # via # azure-identity # azure-storage-blob diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index fd79e7cf4a0..43c49a49527 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -124,7 +124,7 @@ coverage[toml]==7.3.2 # via # coverage # pytest-cov -cryptography==41.0.5 +cryptography==41.0.6 # via # azure-identity # azure-storage-blob From 342464fb1f218b7147d5bda76d208f3ad8ab781f Mon Sep 17 00:00:00 2001 From: Jiwon Park Date: Fri, 19 Jan 2024 11:17:41 +0700 Subject: [PATCH 093/113] fix: Allow trancated timestamps when converting (#3861) Signed-off-by: Attila Toth --- sdk/python/feast/infra/offline_stores/bigquery.py | 10 ++++++++-- sdk/python/feast/infra/utils/aws_utils.py | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/sdk/python/feast/infra/offline_stores/bigquery.py b/sdk/python/feast/infra/offline_stores/bigquery.py index b7910c391c7..0ee82a908ed 100644 --- a/sdk/python/feast/infra/offline_stores/bigquery.py +++ b/sdk/python/feast/infra/offline_stores/bigquery.py @@ -356,7 +356,10 @@ def write_logged_features( # In Pyarrow v13.0, the parquet version was upgraded to v2.6 from v2.4. # Set the coerce_timestamps to "us"(microseconds) for backward compatibility. pyarrow.parquet.write_table( - table=data, where=parquet_temp_file, coerce_timestamps="us" + table=data, + where=parquet_temp_file, + coerce_timestamps="us", + allow_truncated_timestamps=True, ) parquet_temp_file.seek(0) @@ -407,7 +410,10 @@ def offline_write_batch( # In Pyarrow v13.0, the parquet version was upgraded to v2.6 from v2.4. # Set the coerce_timestamps to "us"(microseconds) for backward compatibility. pyarrow.parquet.write_table( - table=table, where=parquet_temp_file, coerce_timestamps="us" + table=table, + where=parquet_temp_file, + coerce_timestamps="us", + allow_truncated_timestamps=True, ) parquet_temp_file.seek(0) diff --git a/sdk/python/feast/infra/utils/aws_utils.py b/sdk/python/feast/infra/utils/aws_utils.py index 728bcab7914..ef83c6d1c62 100644 --- a/sdk/python/feast/infra/utils/aws_utils.py +++ b/sdk/python/feast/infra/utils/aws_utils.py @@ -353,7 +353,12 @@ def upload_arrow_table_to_redshift( with tempfile.TemporaryFile(suffix=".parquet") as parquet_temp_file: # In Pyarrow v13.0, the parquet version was upgraded to v2.6 from v2.4. # Set the coerce_timestamps to "us"(microseconds) for backward compatibility. - pq.write_table(table, parquet_temp_file, coerce_timestamps="us") + pq.write_table( + table, + parquet_temp_file, + coerce_timestamps="us", + allow_truncated_timestamps=True, + ) parquet_temp_file.seek(0) s3_resource.Object(bucket, key).put(Body=parquet_temp_file) From 59e21264dba8187404a8559f4198827c75f1284b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Jan 2024 20:30:34 -0500 Subject: [PATCH 094/113] chore: Bump zod from 3.15.1 to 3.22.3 in /sdk/python/feast/ui (#3816) Bumps [zod](https://github.com/colinhacks/zod) from 3.15.1 to 3.22.3. - [Release notes](https://github.com/colinhacks/zod/releases) - [Changelog](https://github.com/colinhacks/zod/blob/master/CHANGELOG.md) - [Commits](https://github.com/colinhacks/zod/compare/v3.15.1...v3.22.3) --- updated-dependencies: - dependency-name: zod dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- sdk/python/feast/ui/package.json | 2 +- sdk/python/feast/ui/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sdk/python/feast/ui/package.json b/sdk/python/feast/ui/package.json index 1d2951cf57f..f142b0b6448 100644 --- a/sdk/python/feast/ui/package.json +++ b/sdk/python/feast/ui/package.json @@ -24,7 +24,7 @@ "typescript": "^4.6.4", "use-query-params": "^1.2.3", "web-vitals": "^2.1.4", - "zod": "^3.15.1" + "zod": "^3.22.3" }, "scripts": { "start": "react-scripts start", diff --git a/sdk/python/feast/ui/yarn.lock b/sdk/python/feast/ui/yarn.lock index 4d6f690b949..06f4d3f12bb 100644 --- a/sdk/python/feast/ui/yarn.lock +++ b/sdk/python/feast/ui/yarn.lock @@ -11022,10 +11022,10 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zod@^3.11.6, zod@^3.15.1: - version "3.15.1" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.15.1.tgz#9e404cd8002ccffb03baa94cff2e1638ed49d82f" - integrity sha512-WAdjcoOxa4S9oc/u7fTbC3CC7uVqptLLU0LKqS8RDBOrCXp2t5avM8BUfgNVZJymGWAx6SEUYxWPPoYuQ5rgwQ== +zod@^3.11.6, zod@^3.22.3: + version "3.22.3" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.3.tgz#2fbc96118b174290d94e8896371c95629e87a060" + integrity sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug== zwitch@^1.0.0: version "1.0.5" From efbb1e3c48ce5ec0d307ff8db116db6481fd3f47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Jan 2024 20:55:51 -0500 Subject: [PATCH 095/113] chore: Bump google.golang.org/grpc from 1.53.0 to 1.56.3 (#3820) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.53.0 to 1.56.3. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.53.0...v1.56.3) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- go.mod | 8 +- go.sum | 370 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 369 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 20c52d32212..6def9339859 100644 --- a/go.mod +++ b/go.mod @@ -8,14 +8,14 @@ require ( github.com/apache/arrow/go/v8 v8.0.0 github.com/ghodss/yaml v1.0.0 github.com/go-redis/redis/v8 v8.11.4 - github.com/golang/protobuf v1.5.2 + github.com/golang/protobuf v1.5.3 github.com/google/uuid v1.3.0 github.com/mattn/go-sqlite3 v1.14.12 github.com/pkg/errors v0.9.1 github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.7.0 - google.golang.org/grpc v1.53.0 - google.golang.org/protobuf v1.28.1 + google.golang.org/grpc v1.56.3 + google.golang.org/protobuf v1.30.0 ) require ( @@ -43,7 +43,7 @@ require ( golang.org/x/text v0.13.0 // indirect golang.org/x/tools v0.6.0 // indirect golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect diff --git a/go.sum b/go.sum index 990ff9b1ba5..9a33f2c9ee6 100644 --- a/go.sum +++ b/go.sum @@ -35,47 +35,83 @@ cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34h cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= +cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= +cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= +cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= +cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= +cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= +cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= +cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= +cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= +cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= +cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= +cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= +cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= +cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= +cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= +cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= +cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= +cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= +cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= +cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -85,26 +121,42 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= +cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= +cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= +cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= +cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= +cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= +cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= +cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= +cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= @@ -117,224 +169,353 @@ cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= +cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= +cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= +cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= +cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= +cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= +cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= +cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= +cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= +cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= +cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= +cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= +cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= +cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= +cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= +cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= +cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= +cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= +cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= +cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= +cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= +cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= +cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= +cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= +cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= +cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= +cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= +cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= +cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= +cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= +cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= +cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= +cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= +cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= +cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= +cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= +cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= +cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= +cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= +cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= +cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= +cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= +cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= +cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= +cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= +cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= +cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= @@ -344,49 +525,77 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= +cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= +cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= +cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= +cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= +cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= +cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= +cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= +cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= +cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= @@ -397,7 +606,10 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -405,12 +617,16 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= +github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= github.com/apache/arrow/go/v8 v8.0.0 h1:mG1dDlq8aQO4a/PB00T9H19Ga2imvqoFPHI5cykpibs= github.com/apache/arrow/go/v8 v8.0.0/go.mod h1:63co72EKYQT9WKr8Y1Yconk4dysC0t79wNDauYO1ZGg= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.15.0 h1:aGvdaR0v1t9XLgjtBYwxcBvBOTMqClzwE26CHOgjW1Y= github.com/apache/thrift v0.15.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= +github.com/apache/thrift v0.16.0 h1:qEy6UW60iVOlUy+b9ZR0d5WzUWYGOo4HfopoyBaNmoY= +github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -423,6 +639,7 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -451,6 +668,7 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -459,6 +677,7 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -467,6 +686,7 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= @@ -482,9 +702,11 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= +github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= @@ -498,6 +720,7 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -506,10 +729,13 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg= github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -517,6 +743,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/goccy/go-json v0.9.6 h1:5/4CtRQdtsX0sal8fdVhTaiMN01Ri8BExZZ8iRmHQ6E= github.com/goccy/go-json v0.9.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -524,6 +752,7 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -553,8 +782,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= @@ -564,6 +794,8 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/flatbuffers v2.0.5+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/flatbuffers v2.0.6+incompatible h1:XHFReMv7nFFusa+CEokzWbzaYocKXI6C7hdU5Kgh9Lw= github.com/google/flatbuffers v2.0.6+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v2.0.8+incompatible h1:ivUb1cGomAB101ZM1T0nOiWz9pSrTMoa9+EiY7igmkM= +github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -585,6 +817,7 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -608,6 +841,8 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -618,6 +853,7 @@ github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -669,6 +905,7 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/asmfmt v1.3.1/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= @@ -677,6 +914,8 @@ github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= @@ -686,20 +925,29 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= @@ -756,12 +1004,16 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.12/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE= github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -782,6 +1034,7 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= @@ -790,13 +1043,17 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -834,8 +1091,9 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -871,6 +1129,7 @@ go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -914,6 +1173,8 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20211216164055-b2b84827b756/go.mod h1:b9TAUYHmRtqA6klRHApnXMnj+OyLce4yF5cZCUbk2ps= golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4 h1:K3x+yU+fbot38x5bQbU2QqUAVyYLEktdNH2GxZLnM3U= golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 h1:tnebWN09GYg9OLPss1KXj8txwZc6X6uMr6VFdcGNbHw= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -923,6 +1184,10 @@ golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+o golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -956,6 +1221,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1017,8 +1284,12 @@ golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfS golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= @@ -1048,6 +1319,9 @@ golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1061,6 +1335,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1091,6 +1366,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1129,6 +1405,7 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1146,17 +1423,25 @@ golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1170,8 +1455,10 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= @@ -1181,6 +1468,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1233,6 +1521,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1245,11 +1534,14 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1264,9 +1556,12 @@ gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJ gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.9.3 h1:DnoIG+QAMaF5NvxnGe/oKsgKcAc6PcUyl8q0VetfQ8s= gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1319,6 +1614,12 @@ google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91 google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= +google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1434,13 +1735,33 @@ google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1483,8 +1804,11 @@ google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1500,8 +1824,10 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1536,6 +1862,40 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= +modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= +modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= +modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= +modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= From 261c2e35b274ed3235cf3f85b3556b5ee98c39dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Jan 2024 22:28:05 -0500 Subject: [PATCH 096/113] chore: Bump @babel/traverse from 7.16.10 to 7.23.2 in /ui (#3801) Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.16.10 to 7.23.2. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse) --- updated-dependencies: - dependency-name: "@babel/traverse" dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- ui/yarn.lock | 184 ++++++++++++++++++++++++--------------------------- 1 file changed, 86 insertions(+), 98 deletions(-) diff --git a/ui/yarn.lock b/ui/yarn.lock index 78fe6863bff..02c9fd130fe 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -25,12 +25,13 @@ dependencies: "@babel/highlight" "^7.16.7" -"@babel/code-frame@^7.18.6", "@babel/code-frame@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" - integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== +"@babel/code-frame@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== dependencies: - "@babel/highlight" "^7.18.6" + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4", "@babel/compat-data@^7.16.8": version "7.16.8" @@ -106,12 +107,12 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.4.tgz#64a94b7448989f421f919d5239ef553b37bb26bc" - integrity sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA== +"@babel/generator@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" + integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== dependencies: - "@babel/types" "^7.21.4" + "@babel/types" "^7.23.0" "@jridgewell/gen-mapping" "^0.3.2" "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" @@ -190,10 +191,10 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== "@babel/helper-explode-assignable-expression@^7.16.7": version "7.16.7" @@ -211,13 +212,13 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helper-function-name@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" - integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== dependencies: - "@babel/template" "^7.20.7" - "@babel/types" "^7.21.0" + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" "@babel/helper-get-function-arity@^7.16.7": version "7.16.7" @@ -233,12 +234,12 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.22.5" "@babel/helper-member-expression-to-functions@^7.16.7": version "7.16.7" @@ -328,28 +329,38 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.22.5" "@babel/helper-string-parser@^7.19.4": version "7.19.4" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": +"@babel/helper-validator-identifier@^7.19.1": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + "@babel/helper-validator-option@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" @@ -392,16 +403,16 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.10", "@babel/parser@^7.16.12", "@babel/parser@^7.16.7": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.12", "@babel/parser@^7.16.7": version "7.16.12" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.12.tgz#9474794f9a650cf5e2f892444227f98e28cdf8b6" integrity sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A== @@ -411,10 +422,10 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.3.tgz#b07702b982990bf6fdc1da5049a23fece4c5c3d0" integrity sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA== -"@babel/parser@^7.20.7", "@babel/parser@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.4.tgz#94003fdfc520bbe2875d4ae557b43ddb6d880f17" - integrity sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw== +"@babel/parser@^7.22.15", "@babel/parser@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== "@babel/parser@^7.9.4": version "7.19.0" @@ -1176,60 +1187,28 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/template@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" - integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - -"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.10", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.7.2": - version "7.16.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f" - integrity sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.16.8" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.16.10" - "@babel/types" "^7.16.8" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.17.0", "@babel/traverse@^7.17.3": - version "7.17.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" - integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.3" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.17.3" - "@babel/types" "^7.17.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.4.5": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.4.tgz#a836aca7b116634e97a6ed99976236b3282c9d36" - integrity sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q== - dependencies: - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.21.4" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.21.4" - "@babel/types" "^7.21.4" +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.10", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.0", "@babel/traverse@^7.17.3", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" + integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.0" + "@babel/types" "^7.23.0" debug "^4.1.0" globals "^11.1.0" @@ -1249,7 +1228,7 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@babel/types@^7.18.6", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.4": +"@babel/types@^7.18.6", "@babel/types@^7.21.4": version "7.21.4" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.4.tgz#2d5d6bb7908699b3b416409ffd3b5daa25b030d4" integrity sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA== @@ -1258,6 +1237,15 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" +"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" + integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + "@base2/pretty-print-object@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" @@ -3773,7 +3761,7 @@ chalk@4.1.1: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^2.0.0, chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== From 4e6e23f0a12eb0f0cbd68151beb1402c6cfc3b34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Jan 2024 22:56:14 -0500 Subject: [PATCH 097/113] chore: Bump zod from 3.19.1 to 3.22.3 in /ui (#3817) Bumps [zod](https://github.com/colinhacks/zod) from 3.19.1 to 3.22.3. - [Release notes](https://github.com/colinhacks/zod/releases) - [Changelog](https://github.com/colinhacks/zod/blob/master/CHANGELOG.md) - [Commits](https://github.com/colinhacks/zod/compare/v3.19.1...v3.22.3) --- updated-dependencies: - dependency-name: zod dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Attila Toth --- ui/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/yarn.lock b/ui/yarn.lock index 02c9fd130fe..becb6bbd7ba 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -11709,9 +11709,9 @@ yocto-queue@^0.1.0: integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== zod@^3.11.6: - version "3.19.1" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.19.1.tgz#112f074a97b50bfc4772d4ad1576814bd8ac4473" - integrity sha512-LYjZsEDhCdYET9ikFu6dVPGp2YH9DegXjdJToSzD9rO6fy4qiRYFoyEYwps88OseJlPyl2NOe2iJuhEhL7IpEA== + version "3.22.3" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.3.tgz#2fbc96118b174290d94e8896371c95629e87a060" + integrity sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug== zwitch@^1.0.0: version "1.0.5" From a5a87882b8df63a26f28024d59fd0887a2f95a37 Mon Sep 17 00:00:00 2001 From: Shuchu Han Date: Wed, 24 Jan 2024 11:06:54 -0500 Subject: [PATCH 098/113] fix: Correct the returning class proto type of StreamFeatureView to StreamFeatureViewProto instead of FeatureViewProto. (#3843) Signed-off-by: Attila Toth --- sdk/python/feast/feature_view.py | 3 ++- sdk/python/feast/stream_feature_view.py | 7 ++++++- sdk/python/tests/unit/test_feature_views.py | 22 +++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/sdk/python/feast/feature_view.py b/sdk/python/feast/feature_view.py index e26759ba92e..67f9662d317 100644 --- a/sdk/python/feast/feature_view.py +++ b/sdk/python/feast/feature_view.py @@ -17,6 +17,7 @@ from typing import Dict, List, Optional, Tuple, Type from google.protobuf.duration_pb2 import Duration +from google.protobuf.message import Message from typeguard import typechecked from feast import utils @@ -274,7 +275,7 @@ def ensure_valid(self): raise ValueError("Feature view has no entities.") @property - def proto_class(self) -> Type[FeatureViewProto]: + def proto_class(self) -> Type[Message]: return FeatureViewProto def with_join_key_map(self, join_key_map: Dict[str, str]): diff --git a/sdk/python/feast/stream_feature_view.py b/sdk/python/feast/stream_feature_view.py index d3a2164788f..6a204d68136 100644 --- a/sdk/python/feast/stream_feature_view.py +++ b/sdk/python/feast/stream_feature_view.py @@ -3,9 +3,10 @@ import warnings from datetime import datetime, timedelta from types import FunctionType -from typing import Dict, List, Optional, Tuple, Union +from typing import Dict, List, Optional, Tuple, Type, Union import dill +from google.protobuf.message import Message from typeguard import typechecked from feast import flags_helper, utils @@ -298,6 +299,10 @@ def __copy__(self): fv.projection = copy.copy(self.projection) return fv + @property + def proto_class(self) -> Type[Message]: + return StreamFeatureViewProto + def stream_feature_view( *, diff --git a/sdk/python/tests/unit/test_feature_views.py b/sdk/python/tests/unit/test_feature_views.py index 379396e5c63..afef332d372 100644 --- a/sdk/python/tests/unit/test_feature_views.py +++ b/sdk/python/tests/unit/test_feature_views.py @@ -10,6 +10,9 @@ from feast.feature_view import FeatureView from feast.field import Field from feast.infra.offline_stores.file_source import FileSource +from feast.protos.feast.core.StreamFeatureView_pb2 import ( + StreamFeatureView as StreamFeatureViewProto, +) from feast.protos.feast.types.Value_pb2 import ValueType from feast.stream_feature_view import StreamFeatureView, stream_feature_view from feast.types import Float32 @@ -277,3 +280,22 @@ def test_hash(): def test_field_types(): with pytest.raises(TypeError): Field(name="name", dtype=ValueType.INT32) + + +def test_stream_feature_view_proto_type(): + stream_source = KafkaSource( + name="kafka", + timestamp_field="event_timestamp", + kafka_bootstrap_servers="", + message_format=AvroFormat(""), + topic="topic", + batch_source=FileSource(path="some path"), + ) + sfv = StreamFeatureView( + name="test stream featureview proto class", + entities=[], + ttl=timedelta(days=30), + source=stream_source, + aggregations=[], + ) + assert sfv.proto_class is StreamFeatureViewProto From cc313a89d63bcd028ee5aca9bec22bd8af922b80 Mon Sep 17 00:00:00 2001 From: Shuchu Han Date: Wed, 24 Jan 2024 16:16:15 -0500 Subject: [PATCH 099/113] fix: Verify the existence of Registry tables in snowflake before calling CREATE sql command. Allow read-only user to call feast apply. (#3851) Signed-off-by: Shuchu Han Signed-off-by: Attila Toth --- sdk/python/feast/infra/registry/snowflake.py | 71 ++++++++++-- .../registry/snowflake_registry_table.py | 104 ++++++++++++++++++ .../infra/utils/snowflake/snowflake_utils.py | 10 +- 3 files changed, 171 insertions(+), 14 deletions(-) create mode 100644 sdk/python/feast/infra/utils/snowflake/registry/snowflake_registry_table.py diff --git a/sdk/python/feast/infra/registry/snowflake.py b/sdk/python/feast/infra/registry/snowflake.py index 56c7bc1f659..40ec27e7d9c 100644 --- a/sdk/python/feast/infra/registry/snowflake.py +++ b/sdk/python/feast/infra/registry/snowflake.py @@ -124,15 +124,19 @@ def __init__( f'"{self.registry_config.database}"."{self.registry_config.schema_}"' ) - with GetSnowflakeConnection(self.registry_config) as conn: - sql_function_file = f"{os.path.dirname(feast.__file__)}/infra/utils/snowflake/registry/snowflake_table_creation.sql" - with open(sql_function_file, "r") as file: - sqlFile = file.read() - - sqlCommands = sqlFile.split(";") - for command in sqlCommands: - query = command.replace("REGISTRY_PATH", f"{self.registry_path}") - execute_snowflake_statement(conn, query) + if not self._verify_registry_database(): + # Verify the existing resitry database schema from snowflake. If any table names and column types is wrong, run table recreation SQL. + with GetSnowflakeConnection(self.registry_config) as conn: + sql_function_file = f"{os.path.dirname(feast.__file__)}/infra/utils/snowflake/registry/snowflake_table_creation.sql" + with open(sql_function_file, "r") as file: + sqlFile = file.read() + + sqlCommands = sqlFile.split(";") + for command in sqlCommands: + query = command.replace( + "REGISTRY_PATH", f"{self.registry_path}" + ) + execute_snowflake_statement(conn, query) self.cached_registry_proto = self.proto() proto_registry_utils.init_project_metadata(self.cached_registry_proto, project) @@ -145,6 +149,55 @@ def __init__( ) self.project = project + def _verify_registry_database( + self, + ) -> bool: + """Verify the records in registry database. To check: + 1, the 11 tables are existed. + 2, the column types are correct. + + Example return from snowflake's cursor.describe("SELECT * FROM a_table") command: + [ResultMetadata(name='ENTITY_NAME', type_code=2, display_size=None, internal_size=16777216, precision=None, scale=None, is_nullable=False), + ResultMetadata(name='PROJECT_ID', type_code=2, display_size=None, internal_size=16777216, precision=None, scale=None, is_nullable=False), + ResultMetadata(name='LAST_UPDATED_TIMESTAMP', type_code=6, display_size=None, internal_size=None, precision=0, scale=9, is_nullable=False), + ResultMetadata(name='ENTITY_PROTO', type_code=11, display_size=None, internal_size=8388608, precision=None, scale=None, is_nullable=False)] + + Returns: + True if the necessary 11 tables are existed in Snowflake and schema of each table is correct. + False if failure happens. + """ + + from feast.infra.utils.snowflake.registry.snowflake_registry_table import ( + snowflake_registry_table_names_and_column_types as expect_tables, + ) + + res = True + + try: + with GetSnowflakeConnection(self.registry_config) as conn: + for table_name in expect_tables: + result_metadata_list = conn.cursor().describe( + f"SELECT * FROM {table_name}" + ) + for col in result_metadata_list: + if ( + expect_tables[table_name][col.name]["type_code"] + != col.type_code + ): + res = False + break + except Exception as e: + res = False # Set to False for all errors. + logger.debug( + f"Failed to verify Registry tables and columns types with exception: {e}." + ) + finally: + # The implementation in snowflake_utils.py will cache the established connection without re-connection logic. + # conn.close() + pass + + return res + def refresh(self, project: Optional[str] = None): if project: project_metadata = proto_registry_utils.get_project_metadata( diff --git a/sdk/python/feast/infra/utils/snowflake/registry/snowflake_registry_table.py b/sdk/python/feast/infra/utils/snowflake/registry/snowflake_registry_table.py new file mode 100644 index 00000000000..d24fbc27ecb --- /dev/null +++ b/sdk/python/feast/infra/utils/snowflake/registry/snowflake_registry_table.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- + +""" +The table names and column types are following the creation detail listed +in "snowflake_table_creation.sql". + +Snowflake Reference: +1, ResultMetadata: https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-api#label-python-connector-resultmetadata-object +2, Type Codes: https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-api#label-python-connector-type-codes +---------------------------------------------- +type_code String Representation Data Type +0 FIXED NUMBER/INT +1 REAL REAL +2 TEXT VARCHAR/STRING +3 DATE DATE +4 TIMESTAMP TIMESTAMP +5 VARIANT VARIANT +6 TIMESTAMP_LTZ TIMESTAMP_LTZ +7 TIMESTAMP_TZ TIMESTAMP_TZ +8 TIMESTAMP_NTZ TIMESTAMP_TZ +9 OBJECT OBJECT +10 ARRAY ARRAY +11 BINARY BINARY +12 TIME TIME +13 BOOLEAN BOOLEAN +---------------------------------------------- + +(last update: 2023-11-30) + +""" + +snowflake_registry_table_names_and_column_types = { + "DATA_SOURCES": { + "DATA_SOURCE_NAME": {"type_code": 2, "type": "VARCHAR"}, + "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, + "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, + "DATA_SOURCE_PROTO": {"type_code": 11, "type": "BINARY"}, + }, + "ENTITIES": { + "ENTITY_NAME": {"type_code": 2, "type": "VARCHAR"}, + "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, + "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, + "ENTITY_PROTO": {"type_code": 11, "type": "BINARY"}, + }, + "FEAST_METADATA": { + "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, + "METADATA_KEY": {"type_code": 2, "type": "VARCHAR"}, + "METADATA_VALUE": {"type_code": 2, "type": "VARCHAR"}, + "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, + }, + "FEATURE_SERVICES": { + "FEATURE_SERVICE_NAME": {"type_code": 2, "type": "VARCHAR"}, + "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, + "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, + "FEATURE_SERVICE_PROTO": {"type_code": 11, "type": "BINARY"}, + }, + "FEATURE_VIEWS": { + "FEATURE_VIEW_NAME": {"type_code": 2, "type": "VARCHAR"}, + "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, + "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, + "FEATURE_VIEW_PROTO": {"type_code": 11, "type": "BINARY"}, + "MATERIALIZED_INTERVALS": {"type_code": 11, "type": "BINARY"}, + "USER_METADATA": {"type_code": 11, "type": "BINARY"}, + }, + "MANAGED_INFRA": { + "INFRA_NAME": {"type_code": 2, "type": "VARCHAR"}, + "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, + "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, + "INFRA_PROTO": {"type_code": 11, "type": "BINARY"}, + }, + "ON_DEMAND_FEATURE_VIEWS": { + "ON_DEMAND_FEATURE_VIEW_NAME": {"type_code": 2, "type": "VARCHAR"}, + "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, + "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, + "ON_DEMAND_FEATURE_VIEW_PROTO": {"type_code": 11, "type": "BINARY"}, + "USER_METADATA": {"type_code": 11, "type": "BINARY"}, + }, + "REQUEST_FEATURE_VIEWS": { + "REQUEST_FEATURE_VIEW_NAME": {"type_code": 2, "type": "VARCHAR"}, + "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, + "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, + "REQUEST_FEATURE_VIEW_PROTO": {"type_code": 11, "type": "BINARY"}, + "USER_METADATA": {"type_code": 11, "type": "BINARY"}, + }, + "SAVED_DATASETS": { + "SAVED_DATASET_NAME": {"type_code": 2, "type": "VARCHAR"}, + "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, + "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, + "SAVED_DATASET_PROTO": {"type_code": 11, "type": "BINARY"}, + }, + "STREAM_FEATURE_VIEWS": { + "STREAM_FEATURE_VIEW_NAME": {"type_code": 2, "type": "VARCHAR"}, + "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, + "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, + "STREAM_FEATURE_VIEW_PROTO": {"type_code": 11, "type": "BINARY"}, + "USER_METADATA": {"type_code": 11, "type": "BINARY"}, + }, + "VALIDATION_REFERENCES": { + "VALIDATION_REFERENCE_NAME": {"type_code": 2, "type": "VARCHAR"}, + "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, + "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, + "VALIDATION_REFERENCE_PROTO": {"type_code": 11, "type": "BINARY"}, + }, +} diff --git a/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py b/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py index a4cda89a6f6..3a56619bdb5 100644 --- a/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py +++ b/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py @@ -49,19 +49,19 @@ def __init__(self, config: str, autocommit=True): def __enter__(self): - assert self.config.type in [ + assert self.config.type in { "snowflake.registry", "snowflake.offline", "snowflake.engine", "snowflake.online", - ] + } if self.config.type not in _cache: if self.config.type == "snowflake.registry": config_header = "connections.feast_registry" elif self.config.type == "snowflake.offline": config_header = "connections.feast_offline_store" - if self.config.type == "snowflake.engine": + elif self.config.type == "snowflake.engine": config_header = "connections.feast_batch_engine" elif self.config.type == "snowflake.online": config_header = "connections.feast_online_store" @@ -113,11 +113,11 @@ def __exit__(self, exc_type, exc_val, exc_tb): def assert_snowflake_feature_names(feature_view: FeatureView) -> None: for feature in feature_view.features: - assert feature.name not in [ + assert feature.name not in { "entity_key", "feature_name", "feature_value", - ], f"Feature Name: {feature.name} is a protected name to ensure query stability" + }, f"Feature Name: {feature.name} is a protected name to ensure query stability" return None From 56b876816d4941de1331c02a4468e0e99d7d1c4a Mon Sep 17 00:00:00 2001 From: Edson Tirelli Date: Thu, 25 Jan 2024 15:25:19 -0500 Subject: [PATCH 100/113] =?UTF-8?q?revert:=20Verify=20the=20existence=20of?= =?UTF-8?q?=20Registry=20tables=20in=20snowflake=E2=80=A6=20(#3907)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert "fix: Verify the existence of Registry tables in snowflake before calling CREATE sql command. Allow read-only user to call feast apply. (#3851)" This reverts commit 9a3590ea771ca3c3224f5e1a833453144e54284e. Signed-off-by: Edson Tirelli Signed-off-by: Attila Toth --- sdk/python/feast/infra/registry/snowflake.py | 71 ++---------- .../registry/snowflake_registry_table.py | 104 ------------------ .../infra/utils/snowflake/snowflake_utils.py | 10 +- 3 files changed, 14 insertions(+), 171 deletions(-) delete mode 100644 sdk/python/feast/infra/utils/snowflake/registry/snowflake_registry_table.py diff --git a/sdk/python/feast/infra/registry/snowflake.py b/sdk/python/feast/infra/registry/snowflake.py index 40ec27e7d9c..56c7bc1f659 100644 --- a/sdk/python/feast/infra/registry/snowflake.py +++ b/sdk/python/feast/infra/registry/snowflake.py @@ -124,19 +124,15 @@ def __init__( f'"{self.registry_config.database}"."{self.registry_config.schema_}"' ) - if not self._verify_registry_database(): - # Verify the existing resitry database schema from snowflake. If any table names and column types is wrong, run table recreation SQL. - with GetSnowflakeConnection(self.registry_config) as conn: - sql_function_file = f"{os.path.dirname(feast.__file__)}/infra/utils/snowflake/registry/snowflake_table_creation.sql" - with open(sql_function_file, "r") as file: - sqlFile = file.read() - - sqlCommands = sqlFile.split(";") - for command in sqlCommands: - query = command.replace( - "REGISTRY_PATH", f"{self.registry_path}" - ) - execute_snowflake_statement(conn, query) + with GetSnowflakeConnection(self.registry_config) as conn: + sql_function_file = f"{os.path.dirname(feast.__file__)}/infra/utils/snowflake/registry/snowflake_table_creation.sql" + with open(sql_function_file, "r") as file: + sqlFile = file.read() + + sqlCommands = sqlFile.split(";") + for command in sqlCommands: + query = command.replace("REGISTRY_PATH", f"{self.registry_path}") + execute_snowflake_statement(conn, query) self.cached_registry_proto = self.proto() proto_registry_utils.init_project_metadata(self.cached_registry_proto, project) @@ -149,55 +145,6 @@ def __init__( ) self.project = project - def _verify_registry_database( - self, - ) -> bool: - """Verify the records in registry database. To check: - 1, the 11 tables are existed. - 2, the column types are correct. - - Example return from snowflake's cursor.describe("SELECT * FROM a_table") command: - [ResultMetadata(name='ENTITY_NAME', type_code=2, display_size=None, internal_size=16777216, precision=None, scale=None, is_nullable=False), - ResultMetadata(name='PROJECT_ID', type_code=2, display_size=None, internal_size=16777216, precision=None, scale=None, is_nullable=False), - ResultMetadata(name='LAST_UPDATED_TIMESTAMP', type_code=6, display_size=None, internal_size=None, precision=0, scale=9, is_nullable=False), - ResultMetadata(name='ENTITY_PROTO', type_code=11, display_size=None, internal_size=8388608, precision=None, scale=None, is_nullable=False)] - - Returns: - True if the necessary 11 tables are existed in Snowflake and schema of each table is correct. - False if failure happens. - """ - - from feast.infra.utils.snowflake.registry.snowflake_registry_table import ( - snowflake_registry_table_names_and_column_types as expect_tables, - ) - - res = True - - try: - with GetSnowflakeConnection(self.registry_config) as conn: - for table_name in expect_tables: - result_metadata_list = conn.cursor().describe( - f"SELECT * FROM {table_name}" - ) - for col in result_metadata_list: - if ( - expect_tables[table_name][col.name]["type_code"] - != col.type_code - ): - res = False - break - except Exception as e: - res = False # Set to False for all errors. - logger.debug( - f"Failed to verify Registry tables and columns types with exception: {e}." - ) - finally: - # The implementation in snowflake_utils.py will cache the established connection without re-connection logic. - # conn.close() - pass - - return res - def refresh(self, project: Optional[str] = None): if project: project_metadata = proto_registry_utils.get_project_metadata( diff --git a/sdk/python/feast/infra/utils/snowflake/registry/snowflake_registry_table.py b/sdk/python/feast/infra/utils/snowflake/registry/snowflake_registry_table.py deleted file mode 100644 index d24fbc27ecb..00000000000 --- a/sdk/python/feast/infra/utils/snowflake/registry/snowflake_registry_table.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -The table names and column types are following the creation detail listed -in "snowflake_table_creation.sql". - -Snowflake Reference: -1, ResultMetadata: https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-api#label-python-connector-resultmetadata-object -2, Type Codes: https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-api#label-python-connector-type-codes ----------------------------------------------- -type_code String Representation Data Type -0 FIXED NUMBER/INT -1 REAL REAL -2 TEXT VARCHAR/STRING -3 DATE DATE -4 TIMESTAMP TIMESTAMP -5 VARIANT VARIANT -6 TIMESTAMP_LTZ TIMESTAMP_LTZ -7 TIMESTAMP_TZ TIMESTAMP_TZ -8 TIMESTAMP_NTZ TIMESTAMP_TZ -9 OBJECT OBJECT -10 ARRAY ARRAY -11 BINARY BINARY -12 TIME TIME -13 BOOLEAN BOOLEAN ----------------------------------------------- - -(last update: 2023-11-30) - -""" - -snowflake_registry_table_names_and_column_types = { - "DATA_SOURCES": { - "DATA_SOURCE_NAME": {"type_code": 2, "type": "VARCHAR"}, - "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, - "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, - "DATA_SOURCE_PROTO": {"type_code": 11, "type": "BINARY"}, - }, - "ENTITIES": { - "ENTITY_NAME": {"type_code": 2, "type": "VARCHAR"}, - "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, - "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, - "ENTITY_PROTO": {"type_code": 11, "type": "BINARY"}, - }, - "FEAST_METADATA": { - "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, - "METADATA_KEY": {"type_code": 2, "type": "VARCHAR"}, - "METADATA_VALUE": {"type_code": 2, "type": "VARCHAR"}, - "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, - }, - "FEATURE_SERVICES": { - "FEATURE_SERVICE_NAME": {"type_code": 2, "type": "VARCHAR"}, - "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, - "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, - "FEATURE_SERVICE_PROTO": {"type_code": 11, "type": "BINARY"}, - }, - "FEATURE_VIEWS": { - "FEATURE_VIEW_NAME": {"type_code": 2, "type": "VARCHAR"}, - "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, - "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, - "FEATURE_VIEW_PROTO": {"type_code": 11, "type": "BINARY"}, - "MATERIALIZED_INTERVALS": {"type_code": 11, "type": "BINARY"}, - "USER_METADATA": {"type_code": 11, "type": "BINARY"}, - }, - "MANAGED_INFRA": { - "INFRA_NAME": {"type_code": 2, "type": "VARCHAR"}, - "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, - "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, - "INFRA_PROTO": {"type_code": 11, "type": "BINARY"}, - }, - "ON_DEMAND_FEATURE_VIEWS": { - "ON_DEMAND_FEATURE_VIEW_NAME": {"type_code": 2, "type": "VARCHAR"}, - "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, - "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, - "ON_DEMAND_FEATURE_VIEW_PROTO": {"type_code": 11, "type": "BINARY"}, - "USER_METADATA": {"type_code": 11, "type": "BINARY"}, - }, - "REQUEST_FEATURE_VIEWS": { - "REQUEST_FEATURE_VIEW_NAME": {"type_code": 2, "type": "VARCHAR"}, - "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, - "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, - "REQUEST_FEATURE_VIEW_PROTO": {"type_code": 11, "type": "BINARY"}, - "USER_METADATA": {"type_code": 11, "type": "BINARY"}, - }, - "SAVED_DATASETS": { - "SAVED_DATASET_NAME": {"type_code": 2, "type": "VARCHAR"}, - "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, - "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, - "SAVED_DATASET_PROTO": {"type_code": 11, "type": "BINARY"}, - }, - "STREAM_FEATURE_VIEWS": { - "STREAM_FEATURE_VIEW_NAME": {"type_code": 2, "type": "VARCHAR"}, - "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, - "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, - "STREAM_FEATURE_VIEW_PROTO": {"type_code": 11, "type": "BINARY"}, - "USER_METADATA": {"type_code": 11, "type": "BINARY"}, - }, - "VALIDATION_REFERENCES": { - "VALIDATION_REFERENCE_NAME": {"type_code": 2, "type": "VARCHAR"}, - "PROJECT_ID": {"type_code": 2, "type": "VARCHAR"}, - "LAST_UPDATED_TIMESTAMP": {"type_code": 6, "type": "TIMESTAMP_LTZ"}, - "VALIDATION_REFERENCE_PROTO": {"type_code": 11, "type": "BINARY"}, - }, -} diff --git a/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py b/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py index 3a56619bdb5..a4cda89a6f6 100644 --- a/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py +++ b/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py @@ -49,19 +49,19 @@ def __init__(self, config: str, autocommit=True): def __enter__(self): - assert self.config.type in { + assert self.config.type in [ "snowflake.registry", "snowflake.offline", "snowflake.engine", "snowflake.online", - } + ] if self.config.type not in _cache: if self.config.type == "snowflake.registry": config_header = "connections.feast_registry" elif self.config.type == "snowflake.offline": config_header = "connections.feast_offline_store" - elif self.config.type == "snowflake.engine": + if self.config.type == "snowflake.engine": config_header = "connections.feast_batch_engine" elif self.config.type == "snowflake.online": config_header = "connections.feast_online_store" @@ -113,11 +113,11 @@ def __exit__(self, exc_type, exc_val, exc_tb): def assert_snowflake_feature_names(feature_view: FeatureView) -> None: for feature in feature_view.features: - assert feature.name not in { + assert feature.name not in [ "entity_key", "feature_name", "feature_value", - }, f"Feature Name: {feature.name} is a protected name to ensure query stability" + ], f"Feature Name: {feature.name} is a protected name to ensure query stability" return None From 41b0a35cc199d38a5d848696b2862e76439df1ab Mon Sep 17 00:00:00 2001 From: John Lemmon <137814163+JohnLemmonMedely@users.noreply.github.com> Date: Thu, 25 Jan 2024 14:27:04 -0600 Subject: [PATCH 101/113] feat: Add support for arrays in snowflake (#3769) Adds support for arrays in snowflake Signed-off-by: john.lemmon Signed-off-by: Attila Toth --- .../feast/infra/offline_stores/snowflake.py | 31 ++++ .../infra/offline_stores/snowflake_source.py | 6 +- .../snowflake_python_udfs_creation.sql | 56 ++++++ .../snowflake/snowpark/snowflake_udfs.py | 175 ++++++++++++++++++ sdk/python/feast/type_map.py | 8 + sdk/python/tests/data/data_creator.py | 1 + .../feature_repos/repo_configuration.py | 4 +- .../universal/data_sources/snowflake.py | 4 +- .../materialization/test_snowflake.py | 84 +++++++-- 9 files changed, 350 insertions(+), 19 deletions(-) diff --git a/sdk/python/feast/infra/offline_stores/snowflake.py b/sdk/python/feast/infra/offline_stores/snowflake.py index 38568ce79b2..4f11b1ac42c 100644 --- a/sdk/python/feast/infra/offline_stores/snowflake.py +++ b/sdk/python/feast/infra/offline_stores/snowflake.py @@ -1,4 +1,5 @@ import contextlib +import json import os import uuid import warnings @@ -51,6 +52,17 @@ ) from feast.repo_config import FeastConfigBaseModel, RepoConfig from feast.saved_dataset import SavedDatasetStorage +from feast.types import ( + Array, + Bool, + Bytes, + Float32, + Float64, + Int32, + Int64, + String, + UnixTimestamp, +) from feast.usage import log_exceptions_and_usage try: @@ -320,6 +332,7 @@ def query_generator() -> Iterator[str]: on_demand_feature_views=OnDemandFeatureView.get_requested_odfvs( feature_refs, project, registry ), + feature_views=feature_views, metadata=RetrievalMetadata( features=feature_refs, keys=list(entity_schema.keys() - {entity_df_event_timestamp_col}), @@ -398,9 +411,12 @@ def __init__( config: RepoConfig, full_feature_names: bool, on_demand_feature_views: Optional[List[OnDemandFeatureView]] = None, + feature_views: Optional[List[FeatureView]] = None, metadata: Optional[RetrievalMetadata] = None, ): + if feature_views is None: + feature_views = [] if not isinstance(query, str): self._query_generator = query else: @@ -416,6 +432,7 @@ def query_generator() -> Iterator[str]: self.config = config self._full_feature_names = full_feature_names self._on_demand_feature_views = on_demand_feature_views or [] + self._feature_views = feature_views self._metadata = metadata self.export_path: Optional[str] if self.config.offline_store.blob_export_location: @@ -436,6 +453,20 @@ def _to_df_internal(self, timeout: Optional[int] = None) -> pd.DataFrame: self.snowflake_conn, self.to_sql() ).fetch_pandas_all() + for feature_view in self._feature_views: + for feature in feature_view.features: + if feature.dtype in [ + Array(String), + Array(Bytes), + Array(Int32), + Array(Int64), + Array(UnixTimestamp), + Array(Float64), + Array(Float32), + Array(Bool), + ]: + df[feature.name] = [json.loads(x) for x in df[feature.name]] + return df def _to_arrow_internal(self, timeout: Optional[int] = None) -> pyarrow.Table: diff --git a/sdk/python/feast/infra/offline_stores/snowflake_source.py b/sdk/python/feast/infra/offline_stores/snowflake_source.py index 95bd46f1ec1..0cbf82dd1c1 100644 --- a/sdk/python/feast/infra/offline_stores/snowflake_source.py +++ b/sdk/python/feast/infra/offline_stores/snowflake_source.py @@ -279,12 +279,12 @@ def get_table_column_names_and_types( else: row["snowflake_type"] = "NUMBERwSCALE" - elif row["type_code"] in [5, 9, 10, 12]: + elif row["type_code"] in [5, 9, 12]: error = snowflake_unsupported_map[row["type_code"]] raise NotImplementedError( f"The following Snowflake Data Type is not supported: {error}" ) - elif row["type_code"] in [1, 2, 3, 4, 6, 7, 8, 11, 13]: + elif row["type_code"] in [1, 2, 3, 4, 6, 7, 8, 10, 11, 13]: row["snowflake_type"] = snowflake_type_code_map[row["type_code"]] else: raise NotImplementedError( @@ -305,6 +305,7 @@ def get_table_column_names_and_types( 6: "TIMESTAMP_LTZ", 7: "TIMESTAMP_TZ", 8: "TIMESTAMP_NTZ", + 10: "ARRAY", 11: "BINARY", 13: "BOOLEAN", } @@ -312,7 +313,6 @@ def get_table_column_names_and_types( snowflake_unsupported_map = { 5: "VARIANT -- Try converting to VARCHAR", 9: "OBJECT -- Try converting to VARCHAR", - 10: "ARRAY -- Try converting to VARCHAR", 12: "TIME -- Try converting to VARCHAR", } diff --git a/sdk/python/feast/infra/utils/snowflake/snowpark/snowflake_python_udfs_creation.sql b/sdk/python/feast/infra/utils/snowflake/snowpark/snowflake_python_udfs_creation.sql index a197a3ee4cd..a444c0b7c5c 100644 --- a/sdk/python/feast/infra/utils/snowflake/snowpark/snowflake_python_udfs_creation.sql +++ b/sdk/python/feast/infra/utils/snowflake/snowpark/snowflake_python_udfs_creation.sql @@ -14,6 +14,62 @@ CREATE FUNCTION IF NOT EXISTS feast_PROJECT_NAME_snowflake_varchar_to_string_pro HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_varchar_to_string_proto' IMPORTS = ('@STAGE_HOLDER/feast.zip'); +CREATE FUNCTION IF NOT EXISTS feast_PROJECT_NAME_snowflake_array_bytes_to_list_bytes_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_bytes_to_list_bytes_proto' + IMPORTS = ('@STAGE_HOLDER/feast.zip'); + +CREATE FUNCTION IF NOT EXISTS feast_PROJECT_NAME_snowflake_array_varchar_to_list_string_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_varchar_to_list_string_proto' + IMPORTS = ('@STAGE_HOLDER/feast.zip'); + +CREATE FUNCTION IF NOT EXISTS feast_PROJECT_NAME_snowflake_array_number_to_list_int32_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_number_to_list_int32_proto' + IMPORTS = ('@STAGE_HOLDER/feast.zip'); + +CREATE FUNCTION IF NOT EXISTS feast_PROJECT_NAME_snowflake_array_number_to_list_int64_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_number_to_list_int64_proto' + IMPORTS = ('@STAGE_HOLDER/feast.zip'); + +CREATE FUNCTION IF NOT EXISTS feast_PROJECT_NAME_snowflake_array_float_to_list_double_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_float_to_list_double_proto' + IMPORTS = ('@STAGE_HOLDER/feast.zip'); + +CREATE FUNCTION IF NOT EXISTS feast_PROJECT_NAME_snowflake_array_boolean_to_list_bool_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_boolean_to_list_bool_proto' + IMPORTS = ('@STAGE_HOLDER/feast.zip'); + +CREATE FUNCTION IF NOT EXISTS feast_PROJECT_NAME_snowflake_array_timestamp_to_list_unix_timestamp_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_timestamp_to_list_unix_timestamp_proto' + IMPORTS = ('@STAGE_HOLDER/feast.zip'); + CREATE FUNCTION IF NOT EXISTS feast_PROJECT_NAME_snowflake_number_to_int32_proto(df NUMBER) RETURNS BINARY LANGUAGE PYTHON diff --git a/sdk/python/feast/infra/utils/snowflake/snowpark/snowflake_udfs.py b/sdk/python/feast/infra/utils/snowflake/snowpark/snowflake_udfs.py index 02311ca55d6..f5d5f10631f 100644 --- a/sdk/python/feast/infra/utils/snowflake/snowpark/snowflake_udfs.py +++ b/sdk/python/feast/infra/utils/snowflake/snowpark/snowflake_udfs.py @@ -1,6 +1,7 @@ import sys from binascii import unhexlify +import numpy as np import pandas from _snowflake import vectorized @@ -59,6 +60,180 @@ def feast_snowflake_varchar_to_string_proto(df): return df +""" +CREATE OR REPLACE FUNCTION feast_snowflake_array_bytes_to_list_bytes_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_bytes_to_list_bytes_proto' + IMPORTS = ('@feast_stage/feast.zip'); +""" +# ValueType.STRING_LIST = 12 +@vectorized(input=pandas.DataFrame) +def feast_snowflake_array_bytes_to_list_bytes_proto(df): + sys._xoptions["snowflake_partner_attribution"].append("feast") + + # Sometimes bytes come in as strings so we need to convert back to float + numpy_arrays = np.asarray(df[0].to_list()).astype(bytes) + + df = list( + map( + ValueProto.SerializeToString, + python_values_to_proto_values(numpy_arrays, ValueType.BYTES_LIST), + ) + ) + return df + + +""" +CREATE OR REPLACE FUNCTION feast_snowflake_array_varchar_to_list_string_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_varchar_to_list_string_proto' + IMPORTS = ('@feast_stage/feast.zip'); +""" + + +@vectorized(input=pandas.DataFrame) +def feast_snowflake_array_varchar_to_list_string_proto(df): + sys._xoptions["snowflake_partner_attribution"].append("feast") + + df = list( + map( + ValueProto.SerializeToString, + python_values_to_proto_values(df[0].to_numpy(), ValueType.STRING_LIST), + ) + ) + return df + + +""" +CREATE OR REPLACE FUNCTION feast_snowflake_array_number_to_list_int32_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_number_to_list_int32_proto' + IMPORTS = ('@feast_stage/feast.zip'); +""" + + +@vectorized(input=pandas.DataFrame) +def feast_snowflake_array_number_to_list_int32_proto(df): + sys._xoptions["snowflake_partner_attribution"].append("feast") + + df = list( + map( + ValueProto.SerializeToString, + python_values_to_proto_values(df[0].to_numpy(), ValueType.INT32_LIST), + ) + ) + return df + + +""" +CREATE OR REPLACE FUNCTION feast_snowflake_array_number_to_list_int64_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_number_to_list_int64_proto' + IMPORTS = ('@feast_stage/feast.zip'); +""" + + +@vectorized(input=pandas.DataFrame) +def feast_snowflake_array_number_to_list_int64_proto(df): + sys._xoptions["snowflake_partner_attribution"].append("feast") + + df = list( + map( + ValueProto.SerializeToString, + python_values_to_proto_values(df[0].to_numpy(), ValueType.INT64_LIST), + ) + ) + return df + + +""" +CREATE OR REPLACE FUNCTION feast_snowflake_array_float_to_list_double_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_float_to_list_double_proto' + IMPORTS = ('@feast_stage/feast.zip'); +""" + + +@vectorized(input=pandas.DataFrame) +def feast_snowflake_array_float_to_list_double_proto(df): + sys._xoptions["snowflake_partner_attribution"].append("feast") + + numpy_arrays = np.asarray(df[0].to_list()).astype(float) + + df = list( + map( + ValueProto.SerializeToString, + python_values_to_proto_values(numpy_arrays, ValueType.DOUBLE_LIST), + ) + ) + return df + + +""" +CREATE OR REPLACE FUNCTION feast_snowflake_array_boolean_to_list_bool_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_boolean_to_list_bool_proto' + IMPORTS = ('@feast_stage/feast.zip'); +""" + + +@vectorized(input=pandas.DataFrame) +def feast_snowflake_array_boolean_to_list_bool_proto(df): + sys._xoptions["snowflake_partner_attribution"].append("feast") + + df = list( + map( + ValueProto.SerializeToString, + python_values_to_proto_values(df[0].to_numpy(), ValueType.BOOL_LIST), + ) + ) + return df + + +""" +CREATE OR REPLACE FUNCTION feast_snowflake_array_timestamp_to_list_unix_timestamp_proto(df ARRAY) + RETURNS BINARY + LANGUAGE PYTHON + RUNTIME_VERSION = '3.8' + PACKAGES = ('protobuf', 'pandas') + HANDLER = 'feast.infra.utils.snowflake.snowpark.snowflake_udfs.feast_snowflake_array_timestamp_to_list_unix_timestamp_proto' + IMPORTS = ('@feast_stage/feast.zip'); +""" + + +@vectorized(input=pandas.DataFrame) +def feast_snowflake_array_timestamp_to_list_unix_timestamp_proto(df): + sys._xoptions["snowflake_partner_attribution"].append("feast") + + numpy_arrays = np.asarray(df[0].to_list()).astype(np.datetime64) + + df = list( + map( + ValueProto.SerializeToString, + python_values_to_proto_values(numpy_arrays, ValueType.UNIX_TIMESTAMP_LIST), + ) + ) + return df + + """ CREATE OR REPLACE FUNCTION feast_snowflake_number_to_int32_proto(df NUMBER) RETURNS BINARY diff --git a/sdk/python/feast/type_map.py b/sdk/python/feast/type_map.py index 9dbbb5a64ce..e51e1e743bb 100644 --- a/sdk/python/feast/type_map.py +++ b/sdk/python/feast/type_map.py @@ -680,6 +680,14 @@ def _convert_value_name_to_snowflake_udf(value_name: str, project_name: str) -> "FLOAT": f"feast_{project_name}_snowflake_float_to_double_proto", "BOOL": f"feast_{project_name}_snowflake_boolean_to_bool_proto", "UNIX_TIMESTAMP": f"feast_{project_name}_snowflake_timestamp_to_unix_timestamp_proto", + "BYTES_LIST": f"feast_{project_name}_snowflake_array_bytes_to_list_bytes_proto", + "STRING_LIST": f"feast_{project_name}_snowflake_array_varchar_to_list_string_proto", + "INT32_LIST": f"feast_{project_name}_snowflake_array_number_to_list_int32_proto", + "INT64_LIST": f"feast_{project_name}_snowflake_array_number_to_list_int64_proto", + "DOUBLE_LIST": f"feast_{project_name}_snowflake_array_float_to_list_double_proto", + "FLOAT_LIST": f"feast_{project_name}_snowflake_array_float_to_list_double_proto", + "BOOL_LIST": f"feast_{project_name}_snowflake_array_boolean_to_list_bool_proto", + "UNIX_TIMESTAMP_LIST": f"feast_{project_name}_snowflake_array_timestamp_to_list_unix_timestamp_proto", } return name_map[value_name].upper() diff --git a/sdk/python/tests/data/data_creator.py b/sdk/python/tests/data/data_creator.py index 2155468445a..8d5b1979fa3 100644 --- a/sdk/python/tests/data/data_creator.py +++ b/sdk/python/tests/data/data_creator.py @@ -59,6 +59,7 @@ def get_feature_values_for_dtype( "int64": [1, 2, 3, 4, 5], "float": [1.0, None, 3.0, 4.0, 5.0], "string": ["1", None, "3", "4", "5"], + "bytes": [b"1", None, b"3", b"4", b"5"], "bool": [True, None, False, True, False], "datetime": [ datetime(1980, 1, 1), diff --git a/sdk/python/tests/integration/feature_repos/repo_configuration.py b/sdk/python/tests/integration/feature_repos/repo_configuration.py index fda5b3c11de..027dea2c582 100644 --- a/sdk/python/tests/integration/feature_repos/repo_configuration.py +++ b/sdk/python/tests/integration/feature_repos/repo_configuration.py @@ -83,8 +83,8 @@ "password": os.getenv("SNOWFLAKE_CI_PASSWORD", ""), "role": os.getenv("SNOWFLAKE_CI_ROLE", ""), "warehouse": os.getenv("SNOWFLAKE_CI_WAREHOUSE", ""), - "database": "FEAST", - "schema": "ONLINE", + "database": os.getenv("SNOWFLAKE_CI_DATABASE", "FEAST"), + "schema": os.getenv("SNOWFLAKE_CI_SCHEMA_ONLINE", "ONLINE"), } BIGTABLE_CONFIG = { diff --git a/sdk/python/tests/integration/feature_repos/universal/data_sources/snowflake.py b/sdk/python/tests/integration/feature_repos/universal/data_sources/snowflake.py index c7e5961a88a..c14780da97d 100644 --- a/sdk/python/tests/integration/feature_repos/universal/data_sources/snowflake.py +++ b/sdk/python/tests/integration/feature_repos/universal/data_sources/snowflake.py @@ -36,8 +36,8 @@ def __init__(self, project_name: str, *args, **kwargs): password=os.environ["SNOWFLAKE_CI_PASSWORD"], role=os.environ["SNOWFLAKE_CI_ROLE"], warehouse=os.environ["SNOWFLAKE_CI_WAREHOUSE"], - database="FEAST", - schema="OFFLINE", + database=os.environ.get("SNOWFLAKE_CI_DATABASE", "FEAST"), + schema=os.environ.get("SNOWFLAKE_CI_SCHEMA_OFFLINE", "OFFLINE"), storage_integration_name=os.getenv("BLOB_EXPORT_STORAGE_NAME", "FEAST_S3"), blob_export_location=os.getenv( "BLOB_EXPORT_URI", "s3://feast-snowflake-offload/export" diff --git a/sdk/python/tests/integration/materialization/test_snowflake.py b/sdk/python/tests/integration/materialization/test_snowflake.py index 0cf1471dfeb..daa96a87c97 100644 --- a/sdk/python/tests/integration/materialization/test_snowflake.py +++ b/sdk/python/tests/integration/materialization/test_snowflake.py @@ -1,10 +1,13 @@ import os -from datetime import timedelta +from datetime import datetime, timedelta import pytest +from pytz import utc +from feast import Field from feast.entity import Entity from feast.feature_view import FeatureView +from feast.types import Array, Bool, Bytes, Float64, Int32, Int64, String, UnixTimestamp from tests.data.data_creator import create_basic_driver_dataset from tests.integration.feature_repos.integration_test_repo_config import ( IntegrationTestRepoConfig, @@ -24,8 +27,8 @@ "password": os.getenv("SNOWFLAKE_CI_PASSWORD", ""), "role": os.getenv("SNOWFLAKE_CI_ROLE", ""), "warehouse": os.getenv("SNOWFLAKE_CI_WAREHOUSE", ""), - "database": "FEAST", - "schema": "MATERIALIZATION", + "database": os.getenv("SNOWFLAKE_CI_DATABASE", "FEAST"), + "schema": os.getenv("SNOWFLAKE_CI_SCHEMA_MATERIALIZATION", "MATERIALIZATION"), } SNOWFLAKE_ONLINE_CONFIG = { @@ -35,15 +38,16 @@ "password": os.getenv("SNOWFLAKE_CI_PASSWORD", ""), "role": os.getenv("SNOWFLAKE_CI_ROLE", ""), "warehouse": os.getenv("SNOWFLAKE_CI_WAREHOUSE", ""), - "database": "FEAST", - "schema": "ONLINE", + "database": os.getenv("SNOWFLAKE_CI_DATABASE", "FEAST"), + "schema": os.getenv("SNOWFLAKE_CI_SCHEMA_ONLINE", "ONLINE"), } +@pytest.mark.parametrize("online_store", [SNOWFLAKE_ONLINE_CONFIG, "sqlite"]) @pytest.mark.integration -def test_snowflake_materialization_consistency_internal(): +def test_snowflake_materialization_consistency(online_store): snowflake_config = IntegrationTestRepoConfig( - online_store=SNOWFLAKE_ONLINE_CONFIG, + online_store=online_store, offline_store_creator=SnowflakeDataSourceCreator, batch_engine=SNOWFLAKE_ENGINE_CONFIG, ) @@ -84,15 +88,32 @@ def test_snowflake_materialization_consistency_internal(): snowflake_environment.data_source_creator.teardown() +@pytest.mark.parametrize( + "feature_dtype, feast_dtype", + [ + ("string", Array(String)), + ("bytes", Array(Bytes)), + ("int32", Array(Int32)), + ("int64", Array(Int64)), + ("float", Array(Float64)), + ("bool", Array(Bool)), + ("datetime", Array(UnixTimestamp)), + ], +) +@pytest.mark.parametrize("feature_is_empty_list", [False]) +@pytest.mark.parametrize("online_store", [SNOWFLAKE_ONLINE_CONFIG, "sqlite"]) @pytest.mark.integration -def test_snowflake_materialization_consistency_external(): +def test_snowflake_materialization_consistency_internal_with_lists( + feature_dtype, feast_dtype, feature_is_empty_list, online_store +): snowflake_config = IntegrationTestRepoConfig( + online_store=online_store, offline_store_creator=SnowflakeDataSourceCreator, batch_engine=SNOWFLAKE_ENGINE_CONFIG, ) snowflake_environment = construct_test_environment(snowflake_config, None) - df = create_basic_driver_dataset() + df = create_basic_driver_dataset(Int32, feature_dtype, True, feature_is_empty_list) ds = snowflake_environment.data_source_creator.create_data_source( df, snowflake_environment.feature_store.project, @@ -105,23 +126,62 @@ def test_snowflake_materialization_consistency_external(): join_keys=["driver_id"], ) + schema = [ + Field(name="driver_id", dtype=Int32), + Field(name="value", dtype=feast_dtype), + ] driver_stats_fv = FeatureView( name="driver_hourly_stats", entities=[driver], ttl=timedelta(weeks=52), + schema=schema, source=ds, ) try: fs.apply([driver, driver_stats_fv]) - # materialization is run in two steps and - # we use timestamp from generated dataframe as a split point split_dt = df["ts_1"][4].to_pydatetime() - timedelta(seconds=1) print(f"Split datetime: {split_dt}") + now = datetime.utcnow() + + full_feature_names = True + start_date = (now - timedelta(hours=5)).replace(tzinfo=utc) + end_date = split_dt + fs.materialize( + feature_views=[driver_stats_fv.name], + start_date=start_date, + end_date=end_date, + ) + + expected_values = { + "int32": [3] * 2, + "int64": [3] * 2, + "float": [3.0] * 2, + "string": ["3"] * 2, + "bytes": [b"3"] * 2, + "bool": [False] * 2, + "datetime": [datetime(1981, 1, 1, tzinfo=utc)] * 2, + } + expected_value = [] if feature_is_empty_list else expected_values[feature_dtype] + + response_dict = fs.get_online_features( + [f"{driver_stats_fv.name}:value"], + [{"driver_id": 1}], + full_feature_names=full_feature_names, + ).to_dict() + + actual_value = response_dict[f"{driver_stats_fv.name}__value"][0] + assert actual_value is not None, f"Response: {response_dict}" + if feature_dtype == "float": + for actual_num, expected_num in zip(actual_value, expected_value): + assert ( + abs(actual_num - expected_num) < 1e-6 + ), f"Response: {response_dict}, Expected: {expected_value}" + else: + assert actual_value == expected_value - validate_offline_online_store_consistency(fs, driver_stats_fv, split_dt) finally: fs.teardown() snowflake_environment.data_source_creator.teardown() From 38157f6b1bcf7a4f4d14d375816e2da8b4af0d62 Mon Sep 17 00:00:00 2001 From: Alex Vinnik <33845028+alex-vinnik-sp@users.noreply.github.com> Date: Sat, 27 Jan 2024 04:53:31 -0600 Subject: [PATCH 102/113] feat: Support s3gov schema by snowflake offline store during materialization (#3891) Signed-off-by: Attila Toth --- .../feast/infra/offline_stores/snowflake.py | 7 ++- .../infra/offline_stores/test_snowflake.py | 57 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 sdk/python/tests/unit/infra/offline_stores/test_snowflake.py diff --git a/sdk/python/feast/infra/offline_stores/snowflake.py b/sdk/python/feast/infra/offline_stores/snowflake.py index 4f11b1ac42c..dd13ffc96c7 100644 --- a/sdk/python/feast/infra/offline_stores/snowflake.py +++ b/sdk/python/feast/infra/offline_stores/snowflake.py @@ -615,12 +615,17 @@ def to_remote_storage(self) -> List[str]: HEADER = TRUE """ cursor = execute_snowflake_statement(self.snowflake_conn, query) + # s3gov schema is used by Snowflake in AWS govcloud regions + # remove gov portion from schema and pass it to online store upload + native_export_path = self.export_path.replace("s3gov://", "s3://") + return self._get_file_names_from_copy_into(cursor, native_export_path) + def _get_file_names_from_copy_into(self, cursor, native_export_path) -> List[str]: file_name_column_index = [ idx for idx, rm in enumerate(cursor.description) if rm.name == "FILE_NAME" ][0] return [ - f"{self.export_path}/{row[file_name_column_index]}" + f"{native_export_path}/{row[file_name_column_index]}" for row in cursor.fetchall() ] diff --git a/sdk/python/tests/unit/infra/offline_stores/test_snowflake.py b/sdk/python/tests/unit/infra/offline_stores/test_snowflake.py new file mode 100644 index 00000000000..afc3ae97aef --- /dev/null +++ b/sdk/python/tests/unit/infra/offline_stores/test_snowflake.py @@ -0,0 +1,57 @@ +import re +from unittest.mock import ANY, MagicMock, patch + +import pytest + +from feast.infra.offline_stores.snowflake import ( + SnowflakeOfflineStoreConfig, + SnowflakeRetrievalJob, +) +from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig +from feast.repo_config import RepoConfig + + +@pytest.fixture(params=["s3", "s3gov"]) +def retrieval_job(request): + offline_store_config = SnowflakeOfflineStoreConfig( + type="snowflake.offline", + account="snow", + user="snow", + password="snow", + role="snow", + warehouse="snow", + database="FEAST", + schema="OFFLINE", + storage_integration_name="FEAST_S3", + blob_export_location=f"{request.param}://feast-snowflake-offload/export", + ) + retrieval_job = SnowflakeRetrievalJob( + query="SELECT * FROM snowflake", + snowflake_conn=MagicMock(), + config=RepoConfig( + registry="s3://ml-test/repo/registry.db", + project="test", + provider="snowflake.offline", + online_store=SqliteOnlineStoreConfig(type="sqlite"), + offline_store=offline_store_config, + ), + full_feature_names=True, + on_demand_feature_views=[], + ) + return retrieval_job + + +def test_to_remote_storage(retrieval_job): + stored_files = ["just a path", "maybe another"] + with patch.object( + retrieval_job, "to_snowflake", return_value=None + ) as mock_to_snowflake, patch.object( + retrieval_job, "_get_file_names_from_copy_into", return_value=stored_files + ) as mock_get_file_names_from_copy: + assert ( + retrieval_job.to_remote_storage() == stored_files + ), "should return the list of files" + mock_to_snowflake.assert_called_once() + mock_get_file_names_from_copy.assert_called_once_with(ANY, ANY) + native_path = mock_get_file_names_from_copy.call_args[0][1] + assert re.match("^s3://.*", native_path), "path should be s3://*" From 8e851d9792a47a91465afdc38b33c847ffd746ad Mon Sep 17 00:00:00 2001 From: senbong Date: Wed, 31 Jan 2024 01:50:13 +0800 Subject: [PATCH 103/113] fix: Create index only if not exists during MySQL online store update (#3905) Update mysql.py to create index only if not exists during update Signed-off-by: senbong Signed-off-by: Attila Toth --- .../contrib/mysql_online_store/mysql.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sdk/python/feast/infra/online_stores/contrib/mysql_online_store/mysql.py b/sdk/python/feast/infra/online_stores/contrib/mysql_online_store/mysql.py index fa7dd2c2a49..c09cb126f0c 100644 --- a/sdk/python/feast/infra/online_stores/contrib/mysql_online_store/mysql.py +++ b/sdk/python/feast/infra/online_stores/contrib/mysql_online_store/mysql.py @@ -178,8 +178,11 @@ def update( # We don't create any special state for the entities in this implementation. for table in tables_to_keep: + + table_name = _table_id(project, table) + index_name = f"{table_name}_ek" cur.execute( - f"""CREATE TABLE IF NOT EXISTS {_table_id(project, table)} (entity_key VARCHAR(512), + f"""CREATE TABLE IF NOT EXISTS {table_name} (entity_key VARCHAR(512), feature_name VARCHAR(256), value BLOB, event_ts timestamp NULL DEFAULT NULL, @@ -187,9 +190,16 @@ def update( PRIMARY KEY(entity_key, feature_name))""" ) - cur.execute( - f"ALTER TABLE {_table_id(project, table)} ADD INDEX {_table_id(project, table)}_ek (entity_key);" + index_exists = cur.execute( + f""" + SELECT 1 FROM information_schema.statistics + WHERE table_schema = DATABASE() AND table_name = '{table_name}' AND index_name = '{index_name}' + """ ) + if not index_exists: + cur.execute( + f"ALTER TABLE {table_name} ADD INDEX {index_name} (entity_key);" + ) for table in tables_to_delete: _drop_table_and_index(cur, project, table) From 7c3bd2e46766d69e3a1151438dc800ac52d74d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Jord=C3=A0=20Roca?= <108732053+marti-jorda-roca@users.noreply.github.com> Date: Tue, 30 Jan 2024 18:50:28 +0100 Subject: [PATCH 104/113] fix: Bytewax materialization engine fails when loading feature_store.yaml (#3912) * bytewax materialization loads yaml config correctly Signed-off-by: marti-jorda-roca * added postgres dependency for SQL registries Signed-off-by: marti-jorda-roca --------- Signed-off-by: marti-jorda-roca Signed-off-by: Attila Toth --- .../feast/infra/materialization/contrib/bytewax/Dockerfile | 2 +- .../feast/infra/materialization/contrib/bytewax/dataflow.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/Dockerfile b/sdk/python/feast/infra/materialization/contrib/bytewax/Dockerfile index a26661ead35..a7d0af9b416 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/Dockerfile +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/Dockerfile @@ -25,5 +25,5 @@ COPY README.md README.md # git dir to infer the version of feast we're installing. # https://github.com/pypa/setuptools_scm#usage-from-docker # I think it also assumes that this dockerfile is being built from the root of the directory. -RUN --mount=source=.git,target=.git,type=bind pip3 install --no-cache-dir '.[aws,gcp,bytewax,snowflake]' +RUN --mount=source=.git,target=.git,type=bind pip3 install --no-cache-dir '.[aws,gcp,bytewax,snowflake,postgres]' diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py b/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py index 9d9b328c0e9..bbc32cc1651 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/dataflow.py @@ -12,10 +12,10 @@ logging.basicConfig(level=logging.INFO) with open("/var/feast/feature_store.yaml") as f: - feast_config = yaml.safe_load(f) + feast_config = yaml.load(f, Loader=yaml.Loader) with open("/var/feast/bytewax_materialization_config.yaml") as b: - bytewax_config = yaml.safe_load(b) + bytewax_config = yaml.load(b, Loader=yaml.Loader) config = RepoConfig(**feast_config) store = FeatureStore(config=config) From 61a3dbe67435b6eb2f31b11f8b762184453e9f86 Mon Sep 17 00:00:00 2001 From: Willem Pienaar <6728866+woop@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:24:51 -0800 Subject: [PATCH 105/113] Update maintainers.md (#3918) Signed-off-by: Attila Toth --- community/maintainers.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/community/maintainers.md b/community/maintainers.md index 8aca48fd0db..9f8d349a5da 100644 --- a/community/maintainers.md +++ b/community/maintainers.md @@ -9,7 +9,12 @@ In alphabetical order | Name | GitHub Username | Email | Organization | | -------------- | ---------------- |-----------------------------| ------------------ | | Achal Shah | `achals` | achals@gmail.com | Tecton | -| Willem Pienaar | `woop` | will.pienaar@gmail.com | Tecton | +| Edson Tirelli | `etirelli` | ed.tirelli@gmail.com | Red Hat | +| Francisco Javier Arceo | `franciscojavierarceo` | arceofrancisco@gmail.com | Affirm | +| Hao Xu | `hao-affirm` | sduxuhao@gmail.com | JPMorgan | +| Jeremy Ary | `jeremyary` | jeremy.ary@gmail.com | Red Hat | +| Shuchu Han | `shuchu` | shuchu.han@gmail.com | Independent | +| Willem Pienaar | `woop` | will.pienaar@gmail.com | Cleric | | Zhiling Chen | `zhilingc` | chnzhlng@gmail.com | GetGround | ## Emeritus Maintainers From a1cbe3853905df83512813251fa62f7c34a5c132 Mon Sep 17 00:00:00 2001 From: Francisco Javier Arceo Date: Tue, 30 Jan 2024 16:22:51 -0500 Subject: [PATCH 106/113] docs: Updating maintainers.md (#3919) Signed-off-by: Attila Toth --- community/maintainers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community/maintainers.md b/community/maintainers.md index 9f8d349a5da..0b3d4ab6480 100644 --- a/community/maintainers.md +++ b/community/maintainers.md @@ -11,7 +11,7 @@ In alphabetical order | Achal Shah | `achals` | achals@gmail.com | Tecton | | Edson Tirelli | `etirelli` | ed.tirelli@gmail.com | Red Hat | | Francisco Javier Arceo | `franciscojavierarceo` | arceofrancisco@gmail.com | Affirm | -| Hao Xu | `hao-affirm` | sduxuhao@gmail.com | JPMorgan | +| Hao Xu | `HaoXuAI` | sduxuhao@gmail.com | JPMorgan | | Jeremy Ary | `jeremyary` | jeremy.ary@gmail.com | Red Hat | | Shuchu Han | `shuchu` | shuchu.han@gmail.com | Independent | | Willem Pienaar | `woop` | will.pienaar@gmail.com | Cleric | From 125cb1c0f269d3b6b5dfff22f6d84b40cad1c607 Mon Sep 17 00:00:00 2001 From: Francisco Javier Arceo Date: Wed, 31 Jan 2024 17:23:14 -0500 Subject: [PATCH 107/113] docs: Updated development guide to include compiling the protos (#3896) * [docs] updated development guide to include compiling the protos Signed-off-by: franciscojavierarceo * adding note on spinning up the docker image Signed-off-by: franciscojavierarceo --------- Signed-off-by: franciscojavierarceo Signed-off-by: Attila Toth --- docs/project/development-guide.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/project/development-guide.md b/docs/project/development-guide.md index 931d0243d2b..43dae1d678d 100644 --- a/docs/project/development-guide.md +++ b/docs/project/development-guide.md @@ -154,6 +154,16 @@ pip install -e ".[dev]" This will allow the installed feast version to automatically reflect changes to your local development version of Feast without needing to reinstall everytime you make code changes. +10. Compile the protubufs +```sh +make compile-protos-python +``` + +11. Spin up Docker Image +```sh +docker build -t docker-whale -f ./sdk/python/feast/infra/feature_servers/multicloud/Dockerfile . +``` + ### Code Style & Linting Feast Python SDK / CLI codebase: - Conforms to [Black code style](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html) From 2b72364655ef42f512a3ea830f45c89141bdc76b Mon Sep 17 00:00:00 2001 From: Harry Date: Fri, 2 Feb 2024 20:17:46 +0700 Subject: [PATCH 108/113] fix: Prevent spamming pull busybox from dockerhub (#3923) Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- .../contrib/bytewax/bytewax_materialization_engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py index 5c7a719532d..060a47ce585 100644 --- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py +++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py @@ -421,7 +421,7 @@ def _create_job_definition(self, job_id, namespace, pods, env, index_offset=0): } ], "image": "busybox", - "imagePullPolicy": "Always", + "imagePullPolicy": "IfNotPresent", "name": "init-hostfile", "resources": {}, "securityContext": { From 6393ab0e52219ae5db513b181dd817acc8a05c15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 20:00:49 -0500 Subject: [PATCH 109/113] chore: Bump jupyterlab from 4.0.8 to 4.0.11 in /sdk/python/requirements (#3895) Signed-off-by: Attila Toth --- sdk/python/requirements/py3.10-ci-requirements.txt | 2 +- sdk/python/requirements/py3.8-ci-requirements.txt | 2 +- sdk/python/requirements/py3.9-ci-requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index 5e407c1a991..094418cda6b 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -409,7 +409,7 @@ jupyter-server==2.11.2 # notebook-shim jupyter-server-terminals==0.4.4 # via jupyter-server -jupyterlab==4.0.8 +jupyterlab==4.0.11 # via notebook jupyterlab-pygments==0.2.2 # via nbconvert diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index 02eaf6dc307..c477c208355 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -425,7 +425,7 @@ jupyter-server==2.11.2 # notebook-shim jupyter-server-terminals==0.4.4 # via jupyter-server -jupyterlab==4.0.8 +jupyterlab==4.0.11 # via notebook jupyterlab-pygments==0.2.2 # via nbconvert diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index 43c49a49527..6f400fe2408 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -416,7 +416,7 @@ jupyter-server==2.11.2 # notebook-shim jupyter-server-terminals==0.4.4 # via jupyter-server -jupyterlab==4.0.8 +jupyterlab==4.0.11 # via notebook jupyterlab-pygments==0.2.2 # via nbconvert From d9b2cd2672d8e188864202f9440d37d9e837ac84 Mon Sep 17 00:00:00 2001 From: Tornike Gurgenidze Date: Sun, 4 Feb 2024 21:26:12 +0400 Subject: [PATCH 110/113] fix: Remove unnecessary dependency on mysqlclient (#3925) Signed-off-by: Attila Toth --- sdk/python/feast/infra/feature_servers/multicloud/Dockerfile | 1 - .../feast/infra/feature_servers/multicloud/Dockerfile.dev | 1 - sdk/python/requirements/py3.10-ci-requirements.txt | 2 -- sdk/python/requirements/py3.8-ci-requirements.txt | 2 -- sdk/python/requirements/py3.9-ci-requirements.txt | 2 -- sdk/python/tests/unit/test_sql_registry.py | 2 +- setup.py | 2 +- 7 files changed, 2 insertions(+), 10 deletions(-) diff --git a/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile b/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile index c95c515fb4b..fdd8e3ac51d 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile +++ b/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile @@ -4,7 +4,6 @@ RUN apt update && \ apt install -y \ jq \ python3-dev \ - default-libmysqlclient-dev \ build-essential RUN pip install pip --upgrade diff --git a/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile.dev b/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile.dev index ecbc199a5b9..3fc1355d7a8 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile.dev +++ b/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile.dev @@ -4,7 +4,6 @@ RUN apt update && \ apt install -y \ jq \ python3-dev \ - default-libmysqlclient-dev \ build-essential RUN pip install pip --upgrade diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index 094418cda6b..740356907d8 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -472,8 +472,6 @@ mypy-extensions==1.0.0 # mypy mypy-protobuf==3.1.0 # via feast (setup.py) -mysqlclient==2.2.0 - # via feast (setup.py) nbclient==0.9.0 # via nbconvert nbconvert==7.11.0 diff --git a/sdk/python/requirements/py3.8-ci-requirements.txt b/sdk/python/requirements/py3.8-ci-requirements.txt index c477c208355..3bda9e72f9f 100644 --- a/sdk/python/requirements/py3.8-ci-requirements.txt +++ b/sdk/python/requirements/py3.8-ci-requirements.txt @@ -488,8 +488,6 @@ mypy-extensions==1.0.0 # mypy mypy-protobuf==3.1.0 # via feast (setup.py) -mysqlclient==2.2.0 - # via feast (setup.py) nbclient==0.9.0 # via nbconvert nbconvert==7.11.0 diff --git a/sdk/python/requirements/py3.9-ci-requirements.txt b/sdk/python/requirements/py3.9-ci-requirements.txt index 6f400fe2408..6989d5b4ccf 100644 --- a/sdk/python/requirements/py3.9-ci-requirements.txt +++ b/sdk/python/requirements/py3.9-ci-requirements.txt @@ -479,8 +479,6 @@ mypy-extensions==1.0.0 # mypy mypy-protobuf==3.1.0 # via feast (setup.py) -mysqlclient==2.2.0 - # via feast (setup.py) nbclient==0.9.0 # via nbconvert nbconvert==7.11.0 diff --git a/sdk/python/tests/unit/test_sql_registry.py b/sdk/python/tests/unit/test_sql_registry.py index 39896d3a9dd..b96dc6fe770 100644 --- a/sdk/python/tests/unit/test_sql_registry.py +++ b/sdk/python/tests/unit/test_sql_registry.py @@ -103,7 +103,7 @@ def mysql_registry(): registry_config = RegistryConfig( registry_type="sql", - path=f"mysql+mysqldb://{POSTGRES_USER}:{POSTGRES_PASSWORD}@127.0.0.1:{container_port}/{POSTGRES_DB}", + path=f"mysql+pymysql://{POSTGRES_USER}:{POSTGRES_PASSWORD}@127.0.0.1:{container_port}/{POSTGRES_DB}", ) yield SqlRegistry(registry_config, "project", None) diff --git a/setup.py b/setup.py index 33bf76e1819..4905a7697d7 100644 --- a/setup.py +++ b/setup.py @@ -116,7 +116,7 @@ "psycopg2-binary>=2.8.3,<3", ] -MYSQL_REQUIRED = ["mysqlclient", "pymysql", "types-PyMySQL"] +MYSQL_REQUIRED = ["pymysql", "types-PyMySQL"] HBASE_REQUIRED = [ "happybase>=1.2.0,<3", From 3f22fa8b42ee276047c3b2b15f7294a2cb20b45a Mon Sep 17 00:00:00 2001 From: Harry Date: Tue, 6 Feb 2024 12:28:25 +0700 Subject: [PATCH 111/113] ci: Extend python base version for test cases (#3929) Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- .github/workflows/pr_integration_tests.yml | 2 +- .github/workflows/pr_local_integration_tests.yml | 2 +- .github/workflows/unit_tests.yml | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr_integration_tests.yml b/.github/workflows/pr_integration_tests.yml index 73344ec2ddd..26c85b0126e 100644 --- a/.github/workflows/pr_integration_tests.yml +++ b/.github/workflows/pr_integration_tests.yml @@ -86,7 +86,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [ "3.8" ] + python-version: [ "3.8", "3.10" ] os: [ ubuntu-latest ] env: OS: ${{ matrix.os }} diff --git a/.github/workflows/pr_local_integration_tests.yml b/.github/workflows/pr_local_integration_tests.yml index 111a9b51a9c..aeb4100dc85 100644 --- a/.github/workflows/pr_local_integration_tests.yml +++ b/.github/workflows/pr_local_integration_tests.yml @@ -19,7 +19,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [ "3.8" ] + python-version: [ "3.8", "3.10" ] os: [ ubuntu-latest ] env: OS: ${{ matrix.os }} diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index f03cd33346c..31e6d08c743 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -12,8 +12,6 @@ jobs: exclude: - os: macOS-latest python-version: "3.9" - - os: macOS-latest - python-version: "3.10" env: OS: ${{ matrix.os }} PYTHON: ${{ matrix.python-version }} From ce9450351571540da4c9881cb5e38ad3bb6c08db Mon Sep 17 00:00:00 2001 From: Tornike Gurgenidze Date: Wed, 7 Feb 2024 03:26:32 +0400 Subject: [PATCH 112/113] feat: Add gRPC Registry Server (#3924) Signed-off-by: Attila Toth --- protos/feast/registry/RegistryServer.proto | 230 ++++++++++++++++++ sdk/python/feast/cli.py | 21 +- sdk/python/feast/constants.py | 3 + sdk/python/feast/feature_store.py | 7 + .../feast/infra/registry/base_registry.py | 4 +- sdk/python/feast/infra/registry/registry.py | 8 +- sdk/python/feast/registry_server.py | 202 +++++++++++++++ sdk/python/tests/unit/test_registry_server.py | 60 +++++ setup.py | 2 +- 9 files changed, 532 insertions(+), 5 deletions(-) create mode 100644 protos/feast/registry/RegistryServer.proto create mode 100644 sdk/python/feast/registry_server.py create mode 100644 sdk/python/tests/unit/test_registry_server.py diff --git a/protos/feast/registry/RegistryServer.proto b/protos/feast/registry/RegistryServer.proto new file mode 100644 index 00000000000..3e7773e89a4 --- /dev/null +++ b/protos/feast/registry/RegistryServer.proto @@ -0,0 +1,230 @@ +syntax = "proto3"; + +package feast.registry; + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/empty.proto"; +import "feast/core/Registry.proto"; +import "feast/core/Entity.proto"; +import "feast/core/DataSource.proto"; +import "feast/core/FeatureView.proto"; +import "feast/core/RequestFeatureView.proto"; +import "feast/core/StreamFeatureView.proto"; +import "feast/core/OnDemandFeatureView.proto"; +import "feast/core/FeatureService.proto"; +import "feast/core/SavedDataset.proto"; +import "feast/core/ValidationProfile.proto"; +import "feast/core/InfraObject.proto"; + +service RegistryServer{ + // Entity RPCs + rpc GetEntity (GetEntityRequest) returns (feast.core.Entity) {} + rpc ListEntities (ListEntitiesRequest) returns (ListEntitiesResponse) {} + + // DataSource RPCs + rpc GetDataSource (GetDataSourceRequest) returns (feast.core.DataSource) {} + rpc ListDataSources (ListDataSourcesRequest) returns (ListDataSourcesResponse) {} + + // FeatureView RPCs + rpc GetFeatureView (GetFeatureViewRequest) returns (feast.core.FeatureView) {} + rpc ListFeatureViews (ListFeatureViewsRequest) returns (ListFeatureViewsResponse) {} + + // RequestFeatureView RPCs + rpc GetRequestFeatureView (GetRequestFeatureViewRequest) returns (feast.core.RequestFeatureView) {} + rpc ListRequestFeatureViews (ListRequestFeatureViewsRequest) returns (ListRequestFeatureViewsResponse) {} + + // StreamFeatureView RPCs + rpc GetStreamFeatureView (GetStreamFeatureViewRequest) returns (feast.core.StreamFeatureView) {} + rpc ListStreamFeatureViews (ListStreamFeatureViewsRequest) returns (ListStreamFeatureViewsResponse) {} + + // OnDemandFeatureView RPCs + rpc GetOnDemandFeatureView (GetOnDemandFeatureViewRequest) returns (feast.core.OnDemandFeatureView) {} + rpc ListOnDemandFeatureViews (ListOnDemandFeatureViewsRequest) returns (ListOnDemandFeatureViewsResponse) {} + + // FeatureService RPCs + rpc GetFeatureService (GetFeatureServiceRequest) returns (feast.core.FeatureService) {} + rpc ListFeatureServices (ListFeatureServicesRequest) returns (ListFeatureServicesResponse) {} + + // SavedDataset RPCs + rpc GetSavedDataset (GetSavedDatasetRequest) returns (feast.core.SavedDataset) {} + rpc ListSavedDatasets (ListSavedDatasetsRequest) returns (ListSavedDatasetsResponse) {} + + // ValidationReference RPCs + rpc GetValidationReference (GetValidationReferenceRequest) returns (feast.core.ValidationReference) {} + rpc ListValidationReferences (ListValidationReferencesRequest) returns (ListValidationReferencesResponse) {} + + rpc ListProjectMetadata (ListProjectMetadataRequest) returns (ListProjectMetadataResponse) {} + rpc GetInfra (GetInfraRequest) returns (feast.core.Infra) {} + rpc Refresh (RefreshRequest) returns (google.protobuf.Empty) {} + rpc Proto (google.protobuf.Empty) returns (feast.core.Registry) {} + +} + +message RefreshRequest { + string project = 1; +} + +message GetInfraRequest { + string project = 1; + bool allow_cache = 2; +} + +message ListProjectMetadataRequest { + string project = 1; + bool allow_cache = 2; +} + +message ListProjectMetadataResponse { + repeated feast.core.ProjectMetadata project_metadata = 1; +} + +message GetEntityRequest { + string name = 1; + string project = 2; + bool allow_cache = 3; +} + +message ListEntitiesRequest { + string project = 1; + bool allow_cache = 2; +} + +message ListEntitiesResponse { + repeated feast.core.Entity entities = 1; +} + +// DataSources + +message GetDataSourceRequest { + string name = 1; + string project = 2; + bool allow_cache = 3; +} + +message ListDataSourcesRequest { + string project = 1; + bool allow_cache = 2; +} + +message ListDataSourcesResponse { + repeated feast.core.DataSource data_sources = 1; +} + +// FeatureViews + +message GetFeatureViewRequest { + string name = 1; + string project = 2; + bool allow_cache = 3; +} + +message ListFeatureViewsRequest { + string project = 1; + bool allow_cache = 2; +} + +message ListFeatureViewsResponse { + repeated feast.core.FeatureView feature_views = 1; +} + +// RequestFeatureView + +message GetRequestFeatureViewRequest { + string name = 1; + string project = 2; + bool allow_cache = 3; +} + +message ListRequestFeatureViewsRequest { + string project = 1; + bool allow_cache = 2; +} + +message ListRequestFeatureViewsResponse { + repeated feast.core.RequestFeatureView request_feature_views = 1; +} + +// StreamFeatureView + +message GetStreamFeatureViewRequest { + string name = 1; + string project = 2; + bool allow_cache = 3; +} + +message ListStreamFeatureViewsRequest { + string project = 1; + bool allow_cache = 2; +} + +message ListStreamFeatureViewsResponse { + repeated feast.core.StreamFeatureView stream_feature_views = 1; +} + +// OnDemandFeatureView + +message GetOnDemandFeatureViewRequest { + string name = 1; + string project = 2; + bool allow_cache = 3; +} + +message ListOnDemandFeatureViewsRequest { + string project = 1; + bool allow_cache = 2; +} + +message ListOnDemandFeatureViewsResponse { + repeated feast.core.OnDemandFeatureView on_demand_feature_views = 1; +} + +// FeatureServices + +message GetFeatureServiceRequest { + string name = 1; + string project = 2; + bool allow_cache = 3; +} + +message ListFeatureServicesRequest { + string project = 1; + bool allow_cache = 2; +} + +message ListFeatureServicesResponse { + repeated feast.core.FeatureService feature_services = 1; +} + +// SavedDataset + +message GetSavedDatasetRequest { + string name = 1; + string project = 2; + bool allow_cache = 3; +} + +message ListSavedDatasetsRequest { + string project = 1; + bool allow_cache = 2; +} + +message ListSavedDatasetsResponse { + repeated feast.core.SavedDataset saved_datasets = 1; +} + +// ValidationReference + +message GetValidationReferenceRequest { + string name = 1; + string project = 2; + bool allow_cache = 3; +} + +message ListValidationReferencesRequest { + string project = 1; + bool allow_cache = 2; +} + +message ListValidationReferencesResponse { + repeated feast.core.ValidationReference validation_references = 1; +} diff --git a/sdk/python/feast/cli.py b/sdk/python/feast/cli.py index 2eb2c27bcb7..985c44b821f 100644 --- a/sdk/python/feast/cli.py +++ b/sdk/python/feast/cli.py @@ -25,7 +25,10 @@ from pygments import formatters, highlight, lexers from feast import utils -from feast.constants import DEFAULT_FEATURE_TRANSFORMATION_SERVER_PORT +from feast.constants import ( + DEFAULT_FEATURE_TRANSFORMATION_SERVER_PORT, + DEFAULT_REGISTRY_SERVER_PORT, +) from feast.errors import FeastObjectNotFoundException, FeastProviderLoginError from feast.feature_view import FeatureView from feast.infra.contrib.grpc_server import get_grpc_server @@ -753,6 +756,22 @@ def serve_transformations_command(ctx: click.Context, port: int): store.serve_transformations(port) +@cli.command("serve_registry") +@click.option( + "--port", + "-p", + type=click.INT, + default=DEFAULT_REGISTRY_SERVER_PORT, + help="Specify a port for the server", +) +@click.pass_context +def serve_registry_command(ctx: click.Context, port: int): + """Start a registry server locally on a given port.""" + store = create_feature_store(ctx) + + store.serve_registry(port) + + @cli.command("validate") @click.option( "--feature-service", diff --git a/sdk/python/feast/constants.py b/sdk/python/feast/constants.py index 574d79f4167..c022ecba557 100644 --- a/sdk/python/feast/constants.py +++ b/sdk/python/feast/constants.py @@ -44,5 +44,8 @@ # Default FTS port DEFAULT_FEATURE_TRANSFORMATION_SERVER_PORT = 6569 +# Default registry server port +DEFAULT_REGISTRY_SERVER_PORT = 6570 + # Environment variable for feature server docker image tag DOCKER_IMAGE_TAG_ENV_NAME: str = "FEAST_SERVER_DOCKER_IMAGE_TAG" diff --git a/sdk/python/feast/feature_store.py b/sdk/python/feast/feature_store.py index d3f98f80323..4a53672b2e2 100644 --- a/sdk/python/feast/feature_store.py +++ b/sdk/python/feast/feature_store.py @@ -2278,6 +2278,13 @@ def serve_ui( root_path=root_path, ) + @log_exceptions_and_usage + def serve_registry(self, port: int) -> None: + """Start registry server locally on a given port.""" + from feast import registry_server + + registry_server.start_server(self, port) + @log_exceptions_and_usage def serve_transformations(self, port: int) -> None: """Start the feature transformation server locally on a given port.""" diff --git a/sdk/python/feast/infra/registry/base_registry.py b/sdk/python/feast/infra/registry/base_registry.py index 14b098bb123..8928a5800dd 100644 --- a/sdk/python/feast/infra/registry/base_registry.py +++ b/sdk/python/feast/infra/registry/base_registry.py @@ -329,7 +329,9 @@ def list_feature_views( # request feature view operations @abstractmethod - def get_request_feature_view(self, name: str, project: str) -> RequestFeatureView: + def get_request_feature_view( + self, name: str, project: str, allow_cache: bool = False + ) -> RequestFeatureView: """ Retrieves a request feature view. diff --git a/sdk/python/feast/infra/registry/registry.py b/sdk/python/feast/infra/registry/registry.py index 1a72cbb4a58..fc7be75e0d3 100644 --- a/sdk/python/feast/infra/registry/registry.py +++ b/sdk/python/feast/infra/registry/registry.py @@ -528,8 +528,12 @@ def list_feature_views( ) return proto_registry_utils.list_feature_views(registry_proto, project) - def get_request_feature_view(self, name: str, project: str): - registry_proto = self._get_registry_proto(project=project, allow_cache=False) + def get_request_feature_view( + self, name: str, project: str, allow_cache: bool = False + ): + registry_proto = self._get_registry_proto( + project=project, allow_cache=allow_cache + ) return proto_registry_utils.get_request_feature_view( registry_proto, name, project ) diff --git a/sdk/python/feast/registry_server.py b/sdk/python/feast/registry_server.py new file mode 100644 index 00000000000..221715480e5 --- /dev/null +++ b/sdk/python/feast/registry_server.py @@ -0,0 +1,202 @@ +from concurrent import futures + +import grpc +from google.protobuf.empty_pb2 import Empty + +from feast import FeatureStore +from feast.protos.feast.registry import RegistryServer_pb2, RegistryServer_pb2_grpc + + +class RegistryServer(RegistryServer_pb2_grpc.RegistryServerServicer): + def __init__(self, store: FeatureStore) -> None: + super().__init__() + self.proxied_registry = store.registry + + def GetEntity(self, request: RegistryServer_pb2.GetEntityRequest, context): + return self.proxied_registry.get_entity( + name=request.name, project=request.project, allow_cache=request.allow_cache + ).to_proto() + + def ListEntities(self, request, context): + return RegistryServer_pb2.ListEntitiesResponse( + entities=[ + entity.to_proto() + for entity in self.proxied_registry.list_entities( + project=request.project, allow_cache=request.allow_cache + ) + ] + ) + + def GetDataSource(self, request: RegistryServer_pb2.GetDataSourceRequest, context): + return self.proxied_registry.get_data_source( + name=request.name, project=request.project, allow_cache=request.allow_cache + ).to_proto() + + def ListDataSources(self, request, context): + return RegistryServer_pb2.ListDataSourcesResponse( + data_sources=[ + data_source.to_proto() + for data_source in self.proxied_registry.list_data_sources( + project=request.project, allow_cache=request.allow_cache + ) + ] + ) + + def GetFeatureView( + self, request: RegistryServer_pb2.GetFeatureViewRequest, context + ): + return self.proxied_registry.get_feature_view( + name=request.name, project=request.project, allow_cache=request.allow_cache + ).to_proto() + + def ListFeatureViews(self, request, context): + return RegistryServer_pb2.ListFeatureViewsResponse( + feature_views=[ + feature_view.to_proto() + for feature_view in self.proxied_registry.list_feature_views( + project=request.project, allow_cache=request.allow_cache + ) + ] + ) + + def GetRequestFeatureView( + self, request: RegistryServer_pb2.GetRequestFeatureViewRequest, context + ): + return self.proxied_registry.get_request_feature_view( + name=request.name, project=request.project, allow_cache=request.allow_cache + ).to_proto() + + def ListRequestFeatureViews(self, request, context): + return RegistryServer_pb2.ListRequestFeatureViewsResponse( + request_feature_views=[ + request_feature_view.to_proto() + for request_feature_view in self.proxied_registry.list_request_feature_views( + project=request.project, allow_cache=request.allow_cache + ) + ] + ) + + def GetStreamFeatureView( + self, request: RegistryServer_pb2.GetStreamFeatureViewRequest, context + ): + return self.proxied_registry.get_stream_feature_view( + name=request.name, project=request.project, allow_cache=request.allow_cache + ).to_proto() + + def ListStreamFeatureViews(self, request, context): + return RegistryServer_pb2.ListStreamFeatureViewsResponse( + stream_feature_views=[ + stream_feature_view.to_proto() + for stream_feature_view in self.proxied_registry.list_stream_feature_views( + project=request.project, allow_cache=request.allow_cache + ) + ] + ) + + def GetOnDemandFeatureView( + self, request: RegistryServer_pb2.GetOnDemandFeatureViewRequest, context + ): + return self.proxied_registry.get_on_demand_feature_view( + name=request.name, project=request.project, allow_cache=request.allow_cache + ).to_proto() + + def ListOnDemandFeatureViews(self, request, context): + return RegistryServer_pb2.ListOnDemandFeatureViewsResponse( + on_demand_feature_views=[ + on_demand_feature_view.to_proto() + for on_demand_feature_view in self.proxied_registry.list_on_demand_feature_views( + project=request.project, allow_cache=request.allow_cache + ) + ] + ) + + def GetFeatureService( + self, request: RegistryServer_pb2.GetFeatureServiceRequest, context + ): + return self.proxied_registry.get_feature_service( + name=request.name, project=request.project, allow_cache=request.allow_cache + ).to_proto() + + def ListFeatureServices( + self, request: RegistryServer_pb2.ListFeatureServicesRequest, context + ): + return RegistryServer_pb2.ListFeatureServicesResponse( + feature_services=[ + feature_service.to_proto() + for feature_service in self.proxied_registry.list_feature_services( + project=request.project, allow_cache=request.allow_cache + ) + ] + ) + + def GetSavedDataset( + self, request: RegistryServer_pb2.GetSavedDatasetRequest, context + ): + return self.proxied_registry.get_saved_dataset( + name=request.name, project=request.project, allow_cache=request.allow_cache + ).to_proto() + + def ListSavedDatasets( + self, request: RegistryServer_pb2.ListSavedDatasetsRequest, context + ): + return RegistryServer_pb2.ListSavedDatasetsResponse( + saved_datasets=[ + saved_dataset.to_proto() + for saved_dataset in self.proxied_registry.list_saved_datasets( + project=request.project, allow_cache=request.allow_cache + ) + ] + ) + + def GetValidationReference( + self, request: RegistryServer_pb2.GetValidationReferenceRequest, context + ): + return self.proxied_registry.get_validation_reference( + name=request.name, project=request.project, allow_cache=request.allow_cache + ).to_proto() + + def ListValidationReferences( + self, request: RegistryServer_pb2.ListValidationReferencesRequest, context + ): + return RegistryServer_pb2.ListValidationReferencesResponse( + validation_references=[ + validation_reference.to_proto() + for validation_reference in self.proxied_registry.list_validation_references( + project=request.project, allow_cache=request.allow_cache + ) + ] + ) + + def ListProjectMetadata( + self, request: RegistryServer_pb2.ListProjectMetadataRequest, context + ): + return RegistryServer_pb2.ListProjectMetadataResponse( + project_metadata=[ + project_metadata.to_proto() + for project_metadata in self.proxied_registry.list_project_metadata( + project=request.project, allow_cache=request.allow_cache + ) + ] + ) + + def GetInfra(self, request: RegistryServer_pb2.GetInfraRequest, context): + return self.proxied_registry.get_infra( + project=request.project, allow_cache=request.allow_cache + ).to_proto() + + def Refresh(self, request, context): + self.proxied_registry.refresh(request.project) + return Empty() + + def Proto(self, request, context): + return self.proxied_registry.proto() + + +def start_server(store: FeatureStore, port: int): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + RegistryServer_pb2_grpc.add_RegistryServerServicer_to_server( + RegistryServer(store), server + ) + server.add_insecure_port(f"[::]:{port}") + server.start() + server.wait_for_termination() diff --git a/sdk/python/tests/unit/test_registry_server.py b/sdk/python/tests/unit/test_registry_server.py new file mode 100644 index 00000000000..734bbfe19b8 --- /dev/null +++ b/sdk/python/tests/unit/test_registry_server.py @@ -0,0 +1,60 @@ +import assertpy +import grpc_testing +import pytest +from google.protobuf.empty_pb2 import Empty + +from feast import Entity, FeatureStore +from feast.protos.feast.registry import RegistryServer_pb2 +from feast.registry_server import RegistryServer + + +def call_registry_server(server, method: str, request=None): + service = RegistryServer_pb2.DESCRIPTOR.services_by_name["RegistryServer"] + rpc = server.invoke_unary_unary( + service.methods_by_name[method], (), request if request else Empty(), None + ) + + return rpc.termination() + + +@pytest.fixture +def registry_server(environment): + store: FeatureStore = environment.feature_store + + servicer = RegistryServer(store=store) + + return grpc_testing.server_from_dictionary( + {RegistryServer_pb2.DESCRIPTOR.services_by_name["RegistryServer"]: servicer}, + grpc_testing.strict_real_time(), + ) + + +def test_registry_server_get_entity(environment, registry_server): + store: FeatureStore = environment.feature_store + entity = Entity(name="driver", join_keys=["driver_id"]) + store.apply(entity) + + expected = store.get_entity(entity.name) + + get_entity_request = RegistryServer_pb2.GetEntityRequest( + name=entity.name, project=store.project, allow_cache=False + ) + response, trailing_metadata, code, details = call_registry_server( + registry_server, "GetEntity", get_entity_request + ) + response_entity = Entity.from_proto(response) + + assertpy.assert_that(response_entity).is_equal_to(expected) + + +def test_registry_server_proto(environment, registry_server): + store: FeatureStore = environment.feature_store + entity = Entity(name="driver", join_keys=["driver_id"]) + store.apply(entity) + + expected = store.registry.proto() + response, trailing_metadata, code, details = call_registry_server( + registry_server, "Proto" + ) + + assertpy.assert_that(response).is_equal_to(expected) diff --git a/setup.py b/setup.py index 4905a7697d7..29b8dc5a685 100644 --- a/setup.py +++ b/setup.py @@ -234,7 +234,7 @@ else: use_scm_version = None -PROTO_SUBDIRS = ["core", "serving", "types", "storage"] +PROTO_SUBDIRS = ["core", "registry", "serving", "types", "storage"] PYTHON_CODE_PREFIX = "sdk/python" From c646d0381834737cc65483ef4afd40a6ecc0994f Mon Sep 17 00:00:00 2001 From: Harry Date: Wed, 7 Feb 2024 13:50:12 +0700 Subject: [PATCH 113/113] chore: Set upper bound for moto package (#3937) chore: set upper bound for moto package Signed-off-by: Hai Nguyen Signed-off-by: Attila Toth --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 29b8dc5a685..4fb80871b22 100644 --- a/setup.py +++ b/setup.py @@ -155,7 +155,7 @@ "grpcio-testing>=1.56.2,<2", "minio==7.1.0", "mock==2.0.0", - "moto", + "moto<5", "mypy>=0.981,<0.990", "avro==1.10.0", "fsspec<2023.10.0",