We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add materialize and materialize-incremental rest endpoints
**Is your feature request related to a problem? Please describe.**
In multi clustered environments when managing all cronjobs with cron orchestrator tools facing restricted network access to some resources. We use the Rest interface for most important CLI commands as materialize and materialize-incremental.

**Describe the solution you'd like**
adding two endpoints to Python server

**Additional context**
Also we can implement to go server too

Add materialize and materialize-incremental rest endpoints
**Is your feature request related to a problem? Please describe.**
In multi clustered environments when managing all cronjobs with cron orchestrator tools facing restricted network access to some resources. We use the Rest interface for most important CLI commands as materialize and materialize-incremental.

**Describe the solution you'd like**
adding two endpoints to Python server

**Additional context**
Also we can implement to go server too


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sdk/python/feast/feature_server.py`
Content:
```
1 import json
2 import traceback
3 import warnings
4 
5 import gunicorn.app.base
6 import pandas as pd
7 from fastapi import FastAPI, HTTPException, Request, Response, status
8 from fastapi.logger import logger
9 from fastapi.params import Depends
10 from google.protobuf.json_format import MessageToDict, Parse
11 from pydantic import BaseModel
12 
13 import feast
14 from feast import proto_json
15 from feast.data_source import PushMode
16 from feast.errors import PushSourceNotFoundException
17 from feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesRequest
18 
19 
20 # TODO: deprecate this in favor of push features
21 class WriteToFeatureStoreRequest(BaseModel):
22     feature_view_name: str
23     df: dict
24     allow_registry_cache: bool = True
25 
26 
27 class PushFeaturesRequest(BaseModel):
28     push_source_name: str
29     df: dict
30     allow_registry_cache: bool = True
31     to: str = "online"
32 
33 
34 def get_app(store: "feast.FeatureStore"):
35     proto_json.patch()
36 
37     app = FastAPI()
38 
39     async def get_body(request: Request):
40         return await request.body()
41 
42     @app.post("/get-online-features")
43     def get_online_features(body=Depends(get_body)):
44         try:
45             # Validate and parse the request data into GetOnlineFeaturesRequest Protobuf object
46             request_proto = GetOnlineFeaturesRequest()
47             Parse(body, request_proto)
48 
49             # Initialize parameters for FeatureStore.get_online_features(...) call
50             if request_proto.HasField("feature_service"):
51                 features = store.get_feature_service(
52                     request_proto.feature_service, allow_cache=True
53                 )
54             else:
55                 features = list(request_proto.features.val)
56 
57             full_feature_names = request_proto.full_feature_names
58 
59             batch_sizes = [len(v.val) for v in request_proto.entities.values()]
60             num_entities = batch_sizes[0]
61             if any(batch_size != num_entities for batch_size in batch_sizes):
62                 raise HTTPException(status_code=500, detail="Uneven number of columns")
63 
64             response_proto = store._get_online_features(
65                 features=features,
66                 entity_values=request_proto.entities,
67                 full_feature_names=full_feature_names,
68                 native_entity_values=False,
69             ).proto
70 
71             # Convert the Protobuf object to JSON and return it
72             return MessageToDict(  # type: ignore
73                 response_proto, preserving_proto_field_name=True, float_precision=18
74             )
75         except Exception as e:
76             # Print the original exception on the server side
77             logger.exception(traceback.format_exc())
78             # Raise HTTPException to return the error message to the client
79             raise HTTPException(status_code=500, detail=str(e))
80 
81     @app.post("/push")
82     def push(body=Depends(get_body)):
83         try:
84             request = PushFeaturesRequest(**json.loads(body))
85             df = pd.DataFrame(request.df)
86             if request.to == "offline":
87                 to = PushMode.OFFLINE
88             elif request.to == "online":
89                 to = PushMode.ONLINE
90             elif request.to == "online_and_offline":
91                 to = PushMode.ONLINE_AND_OFFLINE
92             else:
93                 raise ValueError(
94                     f"{request.to} is not a supported push format. Please specify one of these ['online', 'offline', 'online_and_offline']."
95                 )
96             store.push(
97                 push_source_name=request.push_source_name,
98                 df=df,
99                 allow_registry_cache=request.allow_registry_cache,
100                 to=to,
101             )
102         except PushSourceNotFoundException as e:
103             # Print the original exception on the server side
104             logger.exception(traceback.format_exc())
105             # Raise HTTPException to return the error message to the client
106             raise HTTPException(status_code=422, detail=str(e))
107         except Exception as e:
108             # Print the original exception on the server side
109             logger.exception(traceback.format_exc())
110             # Raise HTTPException to return the error message to the client
111             raise HTTPException(status_code=500, detail=str(e))
112 
113     @app.post("/write-to-online-store")
114     def write_to_online_store(body=Depends(get_body)):
115         warnings.warn(
116             "write_to_online_store is deprecated. Please consider using /push instead",
117             RuntimeWarning,
118         )
119         try:
120             request = WriteToFeatureStoreRequest(**json.loads(body))
121             df = pd.DataFrame(request.df)
122             store.write_to_online_store(
123                 feature_view_name=request.feature_view_name,
124                 df=df,
125                 allow_registry_cache=request.allow_registry_cache,
126             )
127         except Exception as e:
128             # Print the original exception on the server side
129             logger.exception(traceback.format_exc())
130             # Raise HTTPException to return the error message to the client
131             raise HTTPException(status_code=500, detail=str(e))
132 
133     @app.get("/health")
134     def health():
135         return Response(status_code=status.HTTP_200_OK)
136 
137     return app
138 
139 
140 class FeastServeApplication(gunicorn.app.base.BaseApplication):
141     def __init__(self, store: "feast.FeatureStore", **options):
142         self._app = get_app(store=store)
143         self._options = options
144         super().__init__()
145 
146     def load_config(self):
147         for key, value in self._options.items():
148             if key.lower() in self.cfg.settings and value is not None:
149                 self.cfg.set(key.lower(), value)
150 
151         self.cfg.set("worker_class", "uvicorn.workers.UvicornWorker")
152 
153     def load(self):
154         return self._app
155 
156 
157 def start_server(
158     store: "feast.FeatureStore",
159     host: str,
160     port: int,
161     no_access_log: bool,
162     workers: int,
163     keep_alive_timeout: int,
164 ):
165     FeastServeApplication(
166         store=store,
167         bind=f"{host}:{port}",
168         accesslog=None if no_access_log else "-",
169         workers=workers,
170         keepalive=keep_alive_timeout,
171     ).run()
172
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sdk/python/feast/feature_server.py b/sdk/python/feast/feature_server.py
--- 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 @@
     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 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

{"golden_diff": "diff --git a/sdk/python/feast/feature_server.py b/sdk/python/feast/feature_server.py\n--- a/sdk/python/feast/feature_server.py\n+++ b/sdk/python/feast/feature_server.py\n@@ -1,9 +1,11 @@\n import json\n import traceback\n import warnings\n+from typing import List, Optional\n \n import gunicorn.app.base\n import pandas as pd\n+from dateutil import parser\n from fastapi import FastAPI, HTTPException, Request, Response, status\n from fastapi.logger import logger\n from fastapi.params import Depends\n@@ -11,7 +13,7 @@\n from pydantic import BaseModel\n \n import feast\n-from feast import proto_json\n+from feast import proto_json, utils\n from feast.data_source import PushMode\n from feast.errors import PushSourceNotFoundException\n from feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesRequest\n@@ -31,6 +33,17 @@\n     to: str = \"online\"\n \n \n+class MaterializeRequest(BaseModel):\n+    start_ts: str\n+    end_ts: str\n+    feature_views: Optional[List[str]] = None\n+\n+\n+class MaterializeIncrementalRequest(BaseModel):\n+    end_ts: str\n+    feature_views: Optional[List[str]] = None\n+\n+\n def get_app(store: \"feast.FeatureStore\"):\n     proto_json.patch()\n \n@@ -134,6 +147,34 @@\n     def health():\n         return Response(status_code=status.HTTP_200_OK)\n \n+    @app.post(\"/materialize\")\n+    def materialize(body=Depends(get_body)):\n+        try:\n+            request = MaterializeRequest(**json.loads(body))\n+            store.materialize(\n+                utils.make_tzaware(parser.parse(request.start_ts)),\n+                utils.make_tzaware(parser.parse(request.end_ts)),\n+                request.feature_views,\n+            )\n+        except Exception as e:\n+            # Print the original exception on the server side\n+            logger.exception(traceback.format_exc())\n+            # Raise HTTPException to return the error message to the client\n+            raise HTTPException(status_code=500, detail=str(e))\n+\n+    @app.post(\"/materialize-incremental\")\n+    def materialize_incremental(body=Depends(get_body)):\n+        try:\n+            request = MaterializeIncrementalRequest(**json.loads(body))\n+            store.materialize_incremental(\n+                utils.make_tzaware(parser.parse(request.end_ts)), request.feature_views\n+            )\n+        except Exception as e:\n+            # Print the original exception on the server side\n+            logger.exception(traceback.format_exc())\n+            # Raise HTTPException to return the error message to the client\n+            raise HTTPException(status_code=500, detail=str(e))\n+\n     return app\n", "issue": "Add materialize and materialize-incremental rest endpoints\n**Is your feature request related to a problem? Please describe.**\r\nIn multi clustered environments when managing all cronjobs with cron orchestrator tools facing restricted network access to some resources. We use the Rest interface for most important CLI commands as materialize and materialize-incremental.\r\n\r\n**Describe the solution you'd like**\r\nadding two endpoints to Python server\r\n\r\n**Additional context**\r\nAlso we can implement to go server too\r\n\nAdd materialize and materialize-incremental rest endpoints\n**Is your feature request related to a problem? Please describe.**\r\nIn multi clustered environments when managing all cronjobs with cron orchestrator tools facing restricted network access to some resources. We use the Rest interface for most important CLI commands as materialize and materialize-incremental.\r\n\r\n**Describe the solution you'd like**\r\nadding two endpoints to Python server\r\n\r\n**Additional context**\r\nAlso we can implement to go server too\r\n\n", "before_files": [{"content": "import json\nimport traceback\nimport warnings\n\nimport gunicorn.app.base\nimport pandas as pd\nfrom fastapi import FastAPI, HTTPException, Request, Response, status\nfrom fastapi.logger import logger\nfrom fastapi.params import Depends\nfrom google.protobuf.json_format import MessageToDict, Parse\nfrom pydantic import BaseModel\n\nimport feast\nfrom feast import proto_json\nfrom feast.data_source import PushMode\nfrom feast.errors import PushSourceNotFoundException\nfrom feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesRequest\n\n\n# TODO: deprecate this in favor of push features\nclass WriteToFeatureStoreRequest(BaseModel):\n    feature_view_name: str\n    df: dict\n    allow_registry_cache: bool = True\n\n\nclass PushFeaturesRequest(BaseModel):\n    push_source_name: str\n    df: dict\n    allow_registry_cache: bool = True\n    to: str = \"online\"\n\n\ndef get_app(store: \"feast.FeatureStore\"):\n    proto_json.patch()\n\n    app = FastAPI()\n\n    async def get_body(request: Request):\n        return await request.body()\n\n    @app.post(\"/get-online-features\")\n    def get_online_features(body=Depends(get_body)):\n        try:\n            # Validate and parse the request data into GetOnlineFeaturesRequest Protobuf object\n            request_proto = GetOnlineFeaturesRequest()\n            Parse(body, request_proto)\n\n            # Initialize parameters for FeatureStore.get_online_features(...) call\n            if request_proto.HasField(\"feature_service\"):\n                features = store.get_feature_service(\n                    request_proto.feature_service, allow_cache=True\n                )\n            else:\n                features = list(request_proto.features.val)\n\n            full_feature_names = request_proto.full_feature_names\n\n            batch_sizes = [len(v.val) for v in request_proto.entities.values()]\n            num_entities = batch_sizes[0]\n            if any(batch_size != num_entities for batch_size in batch_sizes):\n                raise HTTPException(status_code=500, detail=\"Uneven number of columns\")\n\n            response_proto = store._get_online_features(\n                features=features,\n                entity_values=request_proto.entities,\n                full_feature_names=full_feature_names,\n                native_entity_values=False,\n            ).proto\n\n            # Convert the Protobuf object to JSON and return it\n            return MessageToDict(  # type: ignore\n                response_proto, preserving_proto_field_name=True, float_precision=18\n            )\n        except Exception as e:\n            # Print the original exception on the server side\n            logger.exception(traceback.format_exc())\n            # Raise HTTPException to return the error message to the client\n            raise HTTPException(status_code=500, detail=str(e))\n\n    @app.post(\"/push\")\n    def push(body=Depends(get_body)):\n        try:\n            request = PushFeaturesRequest(**json.loads(body))\n            df = pd.DataFrame(request.df)\n            if request.to == \"offline\":\n                to = PushMode.OFFLINE\n            elif request.to == \"online\":\n                to = PushMode.ONLINE\n            elif request.to == \"online_and_offline\":\n                to = PushMode.ONLINE_AND_OFFLINE\n            else:\n                raise ValueError(\n                    f\"{request.to} is not a supported push format. Please specify one of these ['online', 'offline', 'online_and_offline'].\"\n                )\n            store.push(\n                push_source_name=request.push_source_name,\n                df=df,\n                allow_registry_cache=request.allow_registry_cache,\n                to=to,\n            )\n        except PushSourceNotFoundException as e:\n            # Print the original exception on the server side\n            logger.exception(traceback.format_exc())\n            # Raise HTTPException to return the error message to the client\n            raise HTTPException(status_code=422, detail=str(e))\n        except Exception as e:\n            # Print the original exception on the server side\n            logger.exception(traceback.format_exc())\n            # Raise HTTPException to return the error message to the client\n            raise HTTPException(status_code=500, detail=str(e))\n\n    @app.post(\"/write-to-online-store\")\n    def write_to_online_store(body=Depends(get_body)):\n        warnings.warn(\n            \"write_to_online_store is deprecated. Please consider using /push instead\",\n            RuntimeWarning,\n        )\n        try:\n            request = WriteToFeatureStoreRequest(**json.loads(body))\n            df = pd.DataFrame(request.df)\n            store.write_to_online_store(\n                feature_view_name=request.feature_view_name,\n                df=df,\n                allow_registry_cache=request.allow_registry_cache,\n            )\n        except Exception as e:\n            # Print the original exception on the server side\n            logger.exception(traceback.format_exc())\n            # Raise HTTPException to return the error message to the client\n            raise HTTPException(status_code=500, detail=str(e))\n\n    @app.get(\"/health\")\n    def health():\n        return Response(status_code=status.HTTP_200_OK)\n\n    return app\n\n\nclass FeastServeApplication(gunicorn.app.base.BaseApplication):\n    def __init__(self, store: \"feast.FeatureStore\", **options):\n        self._app = get_app(store=store)\n        self._options = options\n        super().__init__()\n\n    def load_config(self):\n        for key, value in self._options.items():\n            if key.lower() in self.cfg.settings and value is not None:\n                self.cfg.set(key.lower(), value)\n\n        self.cfg.set(\"worker_class\", \"uvicorn.workers.UvicornWorker\")\n\n    def load(self):\n        return self._app\n\n\ndef start_server(\n    store: \"feast.FeatureStore\",\n    host: str,\n    port: int,\n    no_access_log: bool,\n    workers: int,\n    keep_alive_timeout: int,\n):\n    FeastServeApplication(\n        store=store,\n        bind=f\"{host}:{port}\",\n        accesslog=None if no_access_log else \"-\",\n        workers=workers,\n        keepalive=keep_alive_timeout,\n    ).run()\n", "path": "sdk/python/feast/feature_server.py"}], "after_files": [{"content": "import json\nimport traceback\nimport warnings\nfrom typing import List, Optional\n\nimport gunicorn.app.base\nimport pandas as pd\nfrom dateutil import parser\nfrom fastapi import FastAPI, HTTPException, Request, Response, status\nfrom fastapi.logger import logger\nfrom fastapi.params import Depends\nfrom google.protobuf.json_format import MessageToDict, Parse\nfrom pydantic import BaseModel\n\nimport feast\nfrom feast import proto_json, utils\nfrom feast.data_source import PushMode\nfrom feast.errors import PushSourceNotFoundException\nfrom feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesRequest\n\n\n# TODO: deprecate this in favor of push features\nclass WriteToFeatureStoreRequest(BaseModel):\n    feature_view_name: str\n    df: dict\n    allow_registry_cache: bool = True\n\n\nclass PushFeaturesRequest(BaseModel):\n    push_source_name: str\n    df: dict\n    allow_registry_cache: bool = True\n    to: str = \"online\"\n\n\nclass MaterializeRequest(BaseModel):\n    start_ts: str\n    end_ts: str\n    feature_views: Optional[List[str]] = None\n\n\nclass MaterializeIncrementalRequest(BaseModel):\n    end_ts: str\n    feature_views: Optional[List[str]] = None\n\n\ndef get_app(store: \"feast.FeatureStore\"):\n    proto_json.patch()\n\n    app = FastAPI()\n\n    async def get_body(request: Request):\n        return await request.body()\n\n    @app.post(\"/get-online-features\")\n    def get_online_features(body=Depends(get_body)):\n        try:\n            # Validate and parse the request data into GetOnlineFeaturesRequest Protobuf object\n            request_proto = GetOnlineFeaturesRequest()\n            Parse(body, request_proto)\n\n            # Initialize parameters for FeatureStore.get_online_features(...) call\n            if request_proto.HasField(\"feature_service\"):\n                features = store.get_feature_service(\n                    request_proto.feature_service, allow_cache=True\n                )\n            else:\n                features = list(request_proto.features.val)\n\n            full_feature_names = request_proto.full_feature_names\n\n            batch_sizes = [len(v.val) for v in request_proto.entities.values()]\n            num_entities = batch_sizes[0]\n            if any(batch_size != num_entities for batch_size in batch_sizes):\n                raise HTTPException(status_code=500, detail=\"Uneven number of columns\")\n\n            response_proto = store._get_online_features(\n                features=features,\n                entity_values=request_proto.entities,\n                full_feature_names=full_feature_names,\n                native_entity_values=False,\n            ).proto\n\n            # Convert the Protobuf object to JSON and return it\n            return MessageToDict(  # type: ignore\n                response_proto, preserving_proto_field_name=True, float_precision=18\n            )\n        except Exception as e:\n            # Print the original exception on the server side\n            logger.exception(traceback.format_exc())\n            # Raise HTTPException to return the error message to the client\n            raise HTTPException(status_code=500, detail=str(e))\n\n    @app.post(\"/push\")\n    def push(body=Depends(get_body)):\n        try:\n            request = PushFeaturesRequest(**json.loads(body))\n            df = pd.DataFrame(request.df)\n            if request.to == \"offline\":\n                to = PushMode.OFFLINE\n            elif request.to == \"online\":\n                to = PushMode.ONLINE\n            elif request.to == \"online_and_offline\":\n                to = PushMode.ONLINE_AND_OFFLINE\n            else:\n                raise ValueError(\n                    f\"{request.to} is not a supported push format. Please specify one of these ['online', 'offline', 'online_and_offline'].\"\n                )\n            store.push(\n                push_source_name=request.push_source_name,\n                df=df,\n                allow_registry_cache=request.allow_registry_cache,\n                to=to,\n            )\n        except PushSourceNotFoundException as e:\n            # Print the original exception on the server side\n            logger.exception(traceback.format_exc())\n            # Raise HTTPException to return the error message to the client\n            raise HTTPException(status_code=422, detail=str(e))\n        except Exception as e:\n            # Print the original exception on the server side\n            logger.exception(traceback.format_exc())\n            # Raise HTTPException to return the error message to the client\n            raise HTTPException(status_code=500, detail=str(e))\n\n    @app.post(\"/write-to-online-store\")\n    def write_to_online_store(body=Depends(get_body)):\n        warnings.warn(\n            \"write_to_online_store is deprecated. Please consider using /push instead\",\n            RuntimeWarning,\n        )\n        try:\n            request = WriteToFeatureStoreRequest(**json.loads(body))\n            df = pd.DataFrame(request.df)\n            store.write_to_online_store(\n                feature_view_name=request.feature_view_name,\n                df=df,\n                allow_registry_cache=request.allow_registry_cache,\n            )\n        except Exception as e:\n            # Print the original exception on the server side\n            logger.exception(traceback.format_exc())\n            # Raise HTTPException to return the error message to the client\n            raise HTTPException(status_code=500, detail=str(e))\n\n    @app.get(\"/health\")\n    def health():\n        return Response(status_code=status.HTTP_200_OK)\n\n    @app.post(\"/materialize\")\n    def materialize(body=Depends(get_body)):\n        try:\n            request = MaterializeRequest(**json.loads(body))\n            store.materialize(\n                utils.make_tzaware(parser.parse(request.start_ts)),\n                utils.make_tzaware(parser.parse(request.end_ts)),\n                request.feature_views,\n            )\n        except Exception as e:\n            # Print the original exception on the server side\n            logger.exception(traceback.format_exc())\n            # Raise HTTPException to return the error message to the client\n            raise HTTPException(status_code=500, detail=str(e))\n\n    @app.post(\"/materialize-incremental\")\n    def materialize_incremental(body=Depends(get_body)):\n        try:\n            request = MaterializeIncrementalRequest(**json.loads(body))\n            store.materialize_incremental(\n                utils.make_tzaware(parser.parse(request.end_ts)), request.feature_views\n            )\n        except Exception as e:\n            # Print the original exception on the server side\n            logger.exception(traceback.format_exc())\n            # Raise HTTPException to return the error message to the client\n            raise HTTPException(status_code=500, detail=str(e))\n\n    return app\n\n\nclass FeastServeApplication(gunicorn.app.base.BaseApplication):\n    def __init__(self, store: \"feast.FeatureStore\", **options):\n        self._app = get_app(store=store)\n        self._options = options\n        super().__init__()\n\n    def load_config(self):\n        for key, value in self._options.items():\n            if key.lower() in self.cfg.settings and value is not None:\n                self.cfg.set(key.lower(), value)\n\n        self.cfg.set(\"worker_class\", \"uvicorn.workers.UvicornWorker\")\n\n    def load(self):\n        return self._app\n\n\ndef start_server(\n    store: \"feast.FeatureStore\",\n    host: str,\n    port: int,\n    no_access_log: bool,\n    workers: int,\n    keep_alive_timeout: int,\n):\n    FeastServeApplication(\n        store=store,\n        bind=f\"{host}:{port}\",\n        accesslog=None if no_access_log else \"-\",\n        workers=workers,\n        keepalive=keep_alive_timeout,\n    ).run()\n", "path": "sdk/python/feast/feature_server.py"}]}