Pewarta Proxy

📋 Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

⚙️ Pengaturan Proxy Target

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
docs: document float_precision=18 trade-off; add double_val round-tri…
…p test

Signed-off-by: abhijeet-dhumal <abhijeetdhumal652@gmail.com>
  • Loading branch information
abhijeet-dhumal committed May 27, 2026
commit c559ac5e09345abaaea5d73acef05f3e8c8244c2
37 changes: 35 additions & 2 deletions sdk/python/feast/feature_server_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,36 @@

import logging
from datetime import datetime, timezone
from typing import Any, Dict, Optional
from typing import Any, Callable, Dict, Optional

from starlette.responses import Response

from feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesResponse
from feast.protos.feast.types.Value_pb2 import Value

logger = logging.getLogger(__name__)

try:
import orjson

def _make_json_response(data: Dict[str, Any]) -> Response:
return Response(
content=orjson.dumps(data),
media_type="application/json",
)

except ImportError:
import json

def _make_json_response(data: Dict[str, Any]) -> Response: # type: ignore[misc]
return Response(
content=json.dumps(data).encode(),
media_type="application/json",
)


_make_json_response: Callable[[Dict[str, Any]], Response]

# FieldStatus enum mapping (protos/feast/serving/ServingService.proto)
_STATUS_NAMES: Dict[int, str] = {
0: "INVALID",
Expand All @@ -24,7 +47,17 @@


def convert_response_to_dict(response: GetOnlineFeaturesResponse) -> Dict[str, Any]:
"""Convert GetOnlineFeaturesResponse to dict (matches proto_json.patch() format)."""
"""Convert GetOnlineFeaturesResponse to a JSON-serializable dict.

Matches the structure produced by MessageToDict(proto, preserving_proto_field_name=True)
with proto_json.patch() applied, with one intentional difference:

- double_val fields are returned as Python float objects (json.dumps uses Python 3.1+
shortest round-trip form, ~15-17 sig digits) rather than 18 fixed significant digits
(float_precision=18). Values are numerically identical; only the JSON string length
may differ. This is safe for all ML feature types and avoids unnecessary precision
overhead.
"""
result: Dict[str, Any] = {
"results": [
{
Expand Down
30 changes: 30 additions & 0 deletions sdk/python/tests/unit/test_feature_server_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,36 @@ def test_float_val_precision_matches_message_to_dict(self):
== standard_result["results"][0]["values"]
)

def test_double_val_precision(self):
"""double_val is returned as a Python float (shortest round-trip form).

The upstream code passed float_precision=18 to MessageToDict, which forced 18
significant digits for doubles. Our implementation returns native Python floats
serialized by json.dumps using Python 3.1+ shortest-round-trip representation
(~15–17 sig digits). The value is identical when round-tripped through float64;
the only difference is how many trailing digits appear in the JSON string.
This is an intentional trade-off for speed and is safe for all ML feature values.
"""
import json
import struct

# Use a value with many significant digits
pi = 3.141592653589793
response = GetOnlineFeaturesResponse()
fv = response.results.add()
fv.values.append(Value(double_val=pi))
fv.statuses.append(FieldStatus.PRESENT)

result = convert_response_to_dict(response)
value = result["results"][0]["values"][0]

# Value must round-trip correctly through json.dumps
assert value == pi
round_tripped = json.loads(json.dumps(value))
assert round_tripped == pi
# Verify it encodes as the same float64 bit pattern
assert struct.pack("d", value) == struct.pack("d", pi)

def test_set_types_return_flat_list(self):
"""set types (string_set_val, int64_set_val, etc.) return flat lists.

Expand Down
Loading