diff --git a/.releaserc.js b/.releaserc.js index 114d65d1a2a..c4ad52c9b21 100644 --- a/.releaserc.js +++ b/.releaserc.js @@ -66,6 +66,7 @@ module.exports = { "CHANGELOG.md", "java/pom.xml", "infra/charts/**/*.*", + "infra/feast-operator/**/*.*", "ui/package.json", "sdk/python/feast/ui/package.json", "sdk/python/feast/ui/yarn.lock" diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b7c8be4b77..525b1488a63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.40.1](https://github.com/feast-dev/feast/compare/v0.40.0...v0.40.1) (2024-08-09) + + +### Bug Fixes + +* Add feast-operator files to semantic-release script (v0.40-branch) ([#4383](https://github.com/feast-dev/feast/issues/4383)) ([44f0e84](https://github.com/feast-dev/feast/commit/44f0e84a3e3b2a709fe9b951e57bb37792d06789)) +* Escape special characters in the Postgres password ([#4394](https://github.com/feast-dev/feast/issues/4394)) ([#4396](https://github.com/feast-dev/feast/issues/4396)) ([b456984](https://github.com/feast-dev/feast/commit/b456984fbc1299bb534c5b906b22ed2f55369591)) + # [0.40.0](https://github.com/feast-dev/feast/compare/v0.39.0...v0.40.0) (2024-07-31) diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 1173a693efb..92fa3c692b9 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -19,6 +19,7 @@ * [\[Alpha\] Saved dataset](getting-started/concepts/dataset.md) * [Architecture](getting-started/architecture-and-components/README.md) * [Overview](getting-started/architecture-and-components/overview.md) + * [Language](getting-started/architecture-and-components/language.md) * [Registry](getting-started/architecture-and-components/registry.md) * [Offline store](getting-started/architecture-and-components/offline-store.md) * [Online store](getting-started/architecture-and-components/online-store.md) diff --git a/docs/getting-started/architecture-and-components/README.md b/docs/getting-started/architecture-and-components/README.md index 3a2ebcf6ed5..5a7cc74fae7 100644 --- a/docs/getting-started/architecture-and-components/README.md +++ b/docs/getting-started/architecture-and-components/README.md @@ -1,13 +1,13 @@ # Architecture -{% content-ref url="language.md" %} -[langauge.md](language.md) -{% endcontent-ref %} - {% content-ref url="overview.md" %} [overview.md](overview.md) {% endcontent-ref %} +{% content-ref url="language.md" %} +[language.md](language.md) +{% endcontent-ref %} + {% content-ref url="registry.md" %} [registry.md](registry.md) {% endcontent-ref %} diff --git a/docs/getting-started/architecture-and-components/language.md b/docs/getting-started/architecture-and-components/language.md index 916dff28d74..8127dafb2e9 100644 --- a/docs/getting-started/architecture-and-components/language.md +++ b/docs/getting-started/architecture-and-components/language.md @@ -1,4 +1,6 @@ -# Python: The Language of Production Machine Learning +# Language + +## Python: The Language of Production Machine Learning Use Python to serve your features online. @@ -6,32 +8,32 @@ Use Python to serve your features online. ## Why should you use Python to Serve features for Machine Learning? Python has emerged as the primary language for machine learning, and this extends to feature serving and there are five main reasons Feast recommends using a microservice in Feast. -## 1. Python is the language of Machine Learning +### 1. Python is the language of Machine Learning You should meet your users where they are. Python’s popularity in the machine learning community is undeniable. Its simplicity and readability make it an ideal language for writing and understanding complex algorithms. Python boasts a rich ecosystem of libraries such as TensorFlow, PyTorch, XGBoost, and scikit-learn, which provide robust support for developing and deploying machine learning models and we want Feast in this ecosystem. -## 2. Precomputation is The Way +### 2. Precomputation is The Way Precomputing features is the recommended optimal path to ensure low latency performance. Reducing feature serving to a lightweight database lookup is the ideal pattern, which means the marginal overhead of Python should be tolerable. Precomputation ensures product experiences for downstream services are also fast. Slow user experiences are bad user experiences. Precompute and persist data as much as you can. -## 3. Serving features in another language can lead to skew +### 3. Serving features in another language can lead to skew Ensuring that features used during model training (offline serving) and online serving are available in production to make real-time predictions is critical. When features are initially developed, they are typically written in Python. This is due to the convenience and efficiency provided by Python's data manipulation libraries. However, in a production environment, there is often interest or pressure to rewrite these features in a different language, like Java, Go, or C++, for performance reasons. This reimplementation introduces a significant risk: training and serving skew. Note that there will always be some minor exceptions (e.g., any *Time Since Last Event* types of features) but this should not be the rule. Training and serving skew occurs when there are discrepancies between the features used during model training and those used during prediction. This can lead to degraded model performance, unreliable predictions, and reduced velocity in releasing new features and new models. The process of rewriting features in another language is prone to errors and inconsistencies, which exacerbate this issue. -## 4. Reimplementation is Excessive +### 4. Reimplementation is Excessive Rewriting features in another language is not only risky but also resource-intensive. It requires significant time and effort from engineers to ensure that the features are correctly translated. This process can introduce bugs and inconsistencies, further increasing the risk of training and serving skew. Additionally, maintaining two versions of the same feature codebase adds unnecessary complexity and overhead. More importantly, the opportunity cost of this work is high and requires twice the amount of resourcing. Reimplementing code should only be done when the performance gains are worth the investment. Features should largely be precomputed so the latency performance gains should not be the highest impact work that your team can accomplish. -## 5. Use existing Python Optimizations +### 5. Use existing Python Optimizations Rather than switching languages, it is more efficient to optimize the performance of your feature store while keeping Python as the primary language. Optimization is a two step process. -### Step 1: Quantify latency bottlenecks in your feature calculations +#### Step 1: Quantify latency bottlenecks in your feature calculations Use tools like [CProfile](https://docs.python.org/3/library/profile.html) to understand latency bottlenecks in your code. This will help you prioritize the biggest inefficiencies first. When we initially launched Python native transformations in Python, [profiling the code](https://github.com/feast-dev/feast/issues/4207#issuecomment-2155754504) helped us identify that Pandas resulted in a 10x overhead due to type conversion. -### Step 2: Optimize your feature calculations +#### Step 2: Optimize your feature calculations As mentioned, precomputation is the recommended path. In some cases, you may want fully synchronous writes from your data producer to your online feature store, in which case you will want your feature computations and writes to be very fast. In this case, we recommend optimizing the feature calculation code first. diff --git a/docs/reference/usage.md b/docs/reference/usage.md new file mode 100644 index 00000000000..0ff38af8086 --- /dev/null +++ b/docs/reference/usage.md @@ -0,0 +1,2 @@ +# Usage + diff --git a/infra/charts/feast-feature-server/Chart.yaml b/infra/charts/feast-feature-server/Chart.yaml index af47692f16e..d554458380e 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.40.0 +version: 0.40.1 keywords: - machine learning - big data diff --git a/infra/charts/feast-feature-server/README.md b/infra/charts/feast-feature-server/README.md index 63ff7cf61b2..59bcd321f1d 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.40.0` +Current chart version is `0.40.1` ## Installation @@ -40,7 +40,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.40.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | +| image.tag | string | `"0.40.1"` | 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 0c46bfff854..6ac679d6f84 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.40.0 + tag: 0.40.1 imagePullSecrets: [] nameOverride: "" diff --git a/infra/charts/feast/Chart.yaml b/infra/charts/feast/Chart.yaml index 1f030ca6172..74c2ec8bb7b 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.40.0 +version: 0.40.1 keywords: - machine learning - big data diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index bf8e4d7b8d2..d428eb5c8f5 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.40.0` +Feature store for machine learning Current chart version is `0.40.1` ## 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.40.0 | -| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.40.0 | +| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.40.1 | +| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.40.1 | ## Values diff --git a/infra/charts/feast/charts/feature-server/Chart.yaml b/infra/charts/feast/charts/feature-server/Chart.yaml index f91185be845..29d187b288d 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.40.0 -appVersion: v0.40.0 +version: 0.40.1 +appVersion: v0.40.1 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 c75fc421c62..48d2a56e12a 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.40.0](https://img.shields.io/badge/Version-0.40.0-informational?style=flat-square) ![AppVersion: v0.40.0](https://img.shields.io/badge/AppVersion-v0.40.0-informational?style=flat-square) +![Version: 0.40.1](https://img.shields.io/badge/Version-0.40.1-informational?style=flat-square) ![AppVersion: v0.40.1](https://img.shields.io/badge/AppVersion-v0.40.1-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.40.0"` | Image tag | +| image.tag | string | `"0.40.1"` | 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 d9c964bbca6..4a385926f10 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.40.0 + tag: 0.40.1 # 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 7e336e7a3e8..d19055e183c 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.40.0 -appVersion: v0.40.0 +version: 0.40.1 +appVersion: v0.40.1 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 f90d5bda185..a7b344fd81c 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.40.0](https://img.shields.io/badge/Version-0.40.0-informational?style=flat-square) ![AppVersion: v0.40.0](https://img.shields.io/badge/AppVersion-v0.40.0-informational?style=flat-square) +![Version: 0.40.1](https://img.shields.io/badge/Version-0.40.1-informational?style=flat-square) ![AppVersion: v0.40.1](https://img.shields.io/badge/AppVersion-v0.40.1-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.40.0"` | Image tag | +| image.tag | string | `"0.40.1"` | 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 aee47048e83..89ac444adea 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.40.0 + tag: 0.40.1 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/requirements.yaml b/infra/charts/feast/requirements.yaml index 7b1277fc69a..6d38fbd9017 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.40.0 + version: 0.40.1 condition: feature-server.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: transformation-service alias: transformation-service - version: 0.40.0 + version: 0.40.1 condition: transformation-service.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: redis diff --git a/infra/feast-operator/Makefile b/infra/feast-operator/Makefile index f4464377513..f52911f4321 100644 --- a/infra/feast-operator/Makefile +++ b/infra/feast-operator/Makefile @@ -3,7 +3,7 @@ # To re-generate a bundle for another specific version without changing the standard setup, you can: # - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) # - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.39.0 +VERSION ?= 0.40.0 # CHANNELS define the bundle channels used in the bundle. # Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") diff --git a/infra/feast-operator/config/manager/kustomization.yaml b/infra/feast-operator/config/manager/kustomization.yaml index 1c111ac7ada..116dd148246 100644 --- a/infra/feast-operator/config/manager/kustomization.yaml +++ b/infra/feast-operator/config/manager/kustomization.yaml @@ -5,4 +5,4 @@ kind: Kustomization images: - name: controller newName: feastdev/feast-operator - newTag: 0.39.0 + newTag: 0.40.1 diff --git a/java/pom.xml b/java/pom.xml index 2c1c32792c8..f850c55be20 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -35,7 +35,7 @@ - 0.40.0 + 0.40.1 https://github.com/feast-dev/feast UTF-8 diff --git a/sdk/python/feast/infra/utils/postgres/connection_utils.py b/sdk/python/feast/infra/utils/postgres/connection_utils.py index 7b37ea981f4..3749fc2fc13 100644 --- a/sdk/python/feast/infra/utils/postgres/connection_utils.py +++ b/sdk/python/feast/infra/utils/postgres/connection_utils.py @@ -5,6 +5,7 @@ import psycopg import pyarrow as pa from psycopg import AsyncConnection, Connection +from psycopg.conninfo import make_conninfo from psycopg_pool import AsyncConnectionPool, ConnectionPool from feast.infra.utils.postgres.postgres_config import PostgreSQLConfig @@ -55,13 +56,14 @@ async def _get_connection_pool_async(config: PostgreSQLConfig) -> AsyncConnectio def _get_conninfo(config: PostgreSQLConfig) -> str: """Get the `conninfo` argument required for connection objects.""" - return ( - f"postgresql://{config.user}" - f":{config.password}" - f"@{config.host}" - f":{int(config.port)}" - f"/{config.database}" - ) + psycopg_config = { + "user": config.user, + "password": config.password, + "host": config.host, + "port": int(config.port), + "dbname": config.database, + } + return make_conninfo(conninfo="", **psycopg_config) def _get_conn_kwargs(config: PostgreSQLConfig) -> Dict[str, Any]: diff --git a/sdk/python/feast/ui/package.json b/sdk/python/feast/ui/package.json index 36777ca0be3..b2da53a117c 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.40.0", + "@feast-dev/feast-ui": "0.40.1", "@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 cd1913bbb1f..1bc29dc3d17 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.40.0": - version "0.40.0" - resolved "https://registry.yarnpkg.com/@feast-dev/feast-ui/-/feast-ui-0.40.0.tgz#0dc60cbbd4f63d161927321c0bbf57bbfe6b7d09" - integrity sha512-jiCtMYCBvNSfHCjemFRa0NFIIAR5y6spWBnUZyc4GXY2YxGcznw+PZSzOoi7JrOwpNzNPB0PTBUqJgBAxus20w== +"@feast-dev/feast-ui@0.40.1": + version "0.40.1" + resolved "https://registry.yarnpkg.com/@feast-dev/feast-ui/-/feast-ui-0.40.1.tgz#02080265706c7af6160aef6163a1a2862bdcb333" + integrity sha512-a50VJVN9haL6z2oSbBwq+DwtqmSXvQptjw7oBoucZKZ8D1lybN4MKqqvE1HlAG7mE+kArVZR5SPRQAq++D4xqA== dependencies: "@elastic/datemath" "^5.0.3" "@elastic/eui" "^55.0.1" diff --git a/sdk/python/tests/integration/feature_repos/universal/online_store/postgres.py b/sdk/python/tests/integration/feature_repos/universal/online_store/postgres.py index e4098626411..622ee99e144 100644 --- a/sdk/python/tests/integration/feature_repos/universal/online_store/postgres.py +++ b/sdk/python/tests/integration/feature_repos/universal/online_store/postgres.py @@ -16,7 +16,7 @@ def __init__(self, project_name: str, **kwargs): self.container = PostgresContainer( "postgres:16", username="root", - password="test", + password="test!@#$%", dbname="test", ).with_exposed_ports(5432) @@ -26,7 +26,7 @@ def create_online_store(self) -> Dict[str, str]: "host": "localhost", "type": "postgres", "user": "root", - "password": "test", + "password": "test!@#$%", "database": "test", "port": self.container.get_exposed_port(5432), } @@ -42,7 +42,7 @@ def __init__(self, project_name: str, **kwargs): self.container = ( DockerContainer("pgvector/pgvector:pg16") .with_env("POSTGRES_USER", "root") - .with_env("POSTGRES_PASSWORD", "test") + .with_env("POSTGRES_PASSWORD", "test!@#$%") .with_env("POSTGRES_DB", "test") .with_exposed_ports(5432) .with_volume_mapping( @@ -65,7 +65,7 @@ def create_online_store(self) -> Dict[str, Any]: "host": "localhost", "type": "postgres", "user": "root", - "password": "test", + "password": "test!@#$%", "database": "test", "pgvector_enabled": True, "vector_len": 2, diff --git a/ui/package.json b/ui/package.json index cd80859aa15..957f53355cb 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "@feast-dev/feast-ui", - "version": "0.40.0", + "version": "0.40.1", "private": false, "files": [ "dist"