prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Feast ui cannot parse url path
  ## Expected Behavior 
  
  One of example cases:
  When user navigate localhost:8888/p/order_count_project/feature-view/user_3_and_7_days_order_count should see related feature-view page
  
  ## Current Behavior
  
  One of example cases:
  When user navigate localhost:8888/p/order_count_project/feature-view/user_3_and_7_days_order_count see "Internal Server Error"
  
  ## Steps to reproduce
  
  install feast 0.34.1
  run feast ui
  navigate homepage localhost:8888
  navigate any page (entities or feature-view or data sources doesn't matter)
  you will see the page you clicked at browser search bar like http://localhost:8888/p/order_count_project/data-source 
  then refresh or copy url open in new tab
  you will see internal server error
  
  ### Specifications
  
  - Version: 0.34.1
  - Platform: macos
  - Subsystem: 
  
  ## Possible Solution
  
  ui_server.py file updated recently. commit changes resource finder library and then it returns PosixPath. 
  We should convert to str and add little "/" to "@app.api_route("/p/{path_name:path}", methods=["GET"])" function
  
  
  
  </issue>
  <code>
  [start of sdk/python/feast/ui_server.py]
  1 import json
  2 import threading
  3 from typing import Callable, Optional
  4 
  5 import importlib_resources
  6 import uvicorn
  7 from fastapi import FastAPI, Response
  8 from fastapi.middleware.cors import CORSMiddleware
  9 from fastapi.staticfiles import StaticFiles
  10 
  11 import feast
  12 
  13 
  14 def get_app(
  15     store: "feast.FeatureStore",
  16     project_id: str,
  17     registry_ttl_secs: int,
  18     root_path: str = "",
  19 ):
  20     app = FastAPI()
  21 
  22     app.add_middleware(
  23         CORSMiddleware,
  24         allow_origins=["*"],
  25         allow_credentials=True,
  26         allow_methods=["*"],
  27         allow_headers=["*"],
  28     )
  29 
  30     # Asynchronously refresh registry, notifying shutdown and canceling the active timer if the app is shutting down
  31     registry_proto = None
  32     shutting_down = False
  33     active_timer: Optional[threading.Timer] = None
  34 
  35     def async_refresh():
  36         store.refresh_registry()
  37         nonlocal registry_proto
  38         registry_proto = store.registry.proto()
  39         if shutting_down:
  40             return
  41         nonlocal active_timer
  42         active_timer = threading.Timer(registry_ttl_secs, async_refresh)
  43         active_timer.start()
  44 
  45     @app.on_event("shutdown")
  46     def shutdown_event():
  47         nonlocal shutting_down
  48         shutting_down = True
  49         if active_timer:
  50             active_timer.cancel()
  51 
  52     async_refresh()
  53 
  54     ui_dir_ref = importlib_resources.files(__name__) / "ui/build/"
  55     with importlib_resources.as_file(ui_dir_ref) as ui_dir:
  56         # Initialize with the projects-list.json file
  57         with ui_dir.joinpath("projects-list.json").open(mode="w") as f:
  58             projects_dict = {
  59                 "projects": [
  60                     {
  61                         "name": "Project",
  62                         "description": "Test project",
  63                         "id": project_id,
  64                         "registryPath": f"{root_path}/registry",
  65                     }
  66                 ]
  67             }
  68             f.write(json.dumps(projects_dict))
  69 
  70     @app.get("/registry")
  71     def read_registry():
  72         return Response(
  73             content=registry_proto.SerializeToString(),
  74             media_type="application/octet-stream",
  75         )
  76 
  77     # For all other paths (such as paths that would otherwise be handled by react router), pass to React
  78     @app.api_route("/p/{path_name:path}", methods=["GET"])
  79     def catch_all():
  80         filename = ui_dir + "index.html"
  81 
  82         with open(filename) as f:
  83             content = f.read()
  84 
  85         return Response(content, media_type="text/html")
  86 
  87     app.mount(
  88         "/",
  89         StaticFiles(directory=ui_dir, html=True),
  90         name="site",
  91     )
  92 
  93     return app
  94 
  95 
  96 def start_server(
  97     store: "feast.FeatureStore",
  98     host: str,
  99     port: int,
  100     get_registry_dump: Callable,
  101     project_id: str,
  102     registry_ttl_sec: int,
  103     root_path: str = "",
  104 ):
  105     app = get_app(
  106         store,
  107         project_id,
  108         registry_ttl_sec,
  109         root_path,
  110     )
  111     uvicorn.run(app, host=host, port=port)
  112
  [end of sdk/python/feast/ui_server.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/sdk/python/feast/ui_server.py b/sdk/python/feast/ui_server.py
  --- a/sdk/python/feast/ui_server.py
  +++ b/sdk/python/feast/ui_server.py
  @@ -77,7 +77,7 @@
       # 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()
  
verification_info: {"golden_diff": "diff --git a/sdk/python/feast/ui_server.py b/sdk/python/feast/ui_server.py\n--- a/sdk/python/feast/ui_server.py\n+++ b/sdk/python/feast/ui_server.py\n@@ -77,7 +77,7 @@\n     # For all other paths (such as paths that would otherwise be handled by react router), pass to React\n     @app.api_route(\"/p/{path_name:path}\", methods=[\"GET\"])\n     def catch_all():\n-        filename = ui_dir + \"index.html\"\n+        filename = ui_dir.joinpath(\"index.html\")\n \n         with open(filename) as f:\n             content = f.read()\n", "issue": "Feast ui cannot parse url path\n## Expected Behavior \r\n\r\nOne of example cases:\r\nWhen user navigate localhost:8888/p/order_count_project/feature-view/user_3_and_7_days_order_count should see related feature-view page\r\n\r\n## Current Behavior\r\n\r\nOne of example cases:\r\nWhen user navigate localhost:8888/p/order_count_project/feature-view/user_3_and_7_days_order_count see \"Internal Server Error\"\r\n\r\n## Steps to reproduce\r\n\r\ninstall feast 0.34.1\r\nrun feast ui\r\nnavigate homepage localhost:8888\r\nnavigate any page (entities or feature-view or data sources doesn't matter)\r\nyou will see the page you clicked at browser search bar like http://localhost:8888/p/order_count_project/data-source \r\nthen refresh or copy url open in new tab\r\nyou will see internal server error\r\n\r\n### Specifications\r\n\r\n- Version: 0.34.1\r\n- Platform: macos\r\n- Subsystem: \r\n\r\n## Possible Solution\r\n\r\nui_server.py file updated recently. commit changes resource finder library and then it returns PosixPath. \r\nWe should convert to str and add little \"/\" to \"@app.api_route(\"/p/{path_name:path}\", methods=[\"GET\"])\" function\r\n\r\n\n", "before_files": [{"content": "import json\nimport threading\nfrom typing import Callable, Optional\n\nimport importlib_resources\nimport uvicorn\nfrom fastapi import FastAPI, Response\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom fastapi.staticfiles import StaticFiles\n\nimport feast\n\n\ndef get_app(\n    store: \"feast.FeatureStore\",\n    project_id: str,\n    registry_ttl_secs: int,\n    root_path: str = \"\",\n):\n    app = FastAPI()\n\n    app.add_middleware(\n        CORSMiddleware,\n        allow_origins=[\"*\"],\n        allow_credentials=True,\n        allow_methods=[\"*\"],\n        allow_headers=[\"*\"],\n    )\n\n    # Asynchronously refresh registry, notifying shutdown and canceling the active timer if the app is shutting down\n    registry_proto = None\n    shutting_down = False\n    active_timer: Optional[threading.Timer] = None\n\n    def async_refresh():\n        store.refresh_registry()\n        nonlocal registry_proto\n        registry_proto = store.registry.proto()\n        if shutting_down:\n            return\n        nonlocal active_timer\n        active_timer = threading.Timer(registry_ttl_secs, async_refresh)\n        active_timer.start()\n\n    @app.on_event(\"shutdown\")\n    def shutdown_event():\n        nonlocal shutting_down\n        shutting_down = True\n        if active_timer:\n            active_timer.cancel()\n\n    async_refresh()\n\n    ui_dir_ref = importlib_resources.files(__name__) / \"ui/build/\"\n    with importlib_resources.as_file(ui_dir_ref) as ui_dir:\n        # Initialize with the projects-list.json file\n        with ui_dir.joinpath(\"projects-list.json\").open(mode=\"w\") as f:\n            projects_dict = {\n                \"projects\": [\n                    {\n                        \"name\": \"Project\",\n                        \"description\": \"Test project\",\n                        \"id\": project_id,\n                        \"registryPath\": f\"{root_path}/registry\",\n                    }\n                ]\n            }\n            f.write(json.dumps(projects_dict))\n\n    @app.get(\"/registry\")\n    def read_registry():\n        return Response(\n            content=registry_proto.SerializeToString(),\n            media_type=\"application/octet-stream\",\n        )\n\n    # For all other paths (such as paths that would otherwise be handled by react router), pass to React\n    @app.api_route(\"/p/{path_name:path}\", methods=[\"GET\"])\n    def catch_all():\n        filename = ui_dir + \"index.html\"\n\n        with open(filename) as f:\n            content = f.read()\n\n        return Response(content, media_type=\"text/html\")\n\n    app.mount(\n        \"/\",\n        StaticFiles(directory=ui_dir, html=True),\n        name=\"site\",\n    )\n\n    return app\n\n\ndef start_server(\n    store: \"feast.FeatureStore\",\n    host: str,\n    port: int,\n    get_registry_dump: Callable,\n    project_id: str,\n    registry_ttl_sec: int,\n    root_path: str = \"\",\n):\n    app = get_app(\n        store,\n        project_id,\n        registry_ttl_sec,\n        root_path,\n    )\n    uvicorn.run(app, host=host, port=port)\n", "path": "sdk/python/feast/ui_server.py"}]}