Skip to content

Commit ebe773c

Browse files
committed
[IMP]fastapi: enable multi-slash routes
1 parent b44eefb commit ebe773c

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed

fastapi/demo/fastapi_endpoint_demo.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,15 @@ methods. See documentation to learn more about how to create a new app.
4444
<field name="demo_auth_method">http_basic</field>
4545
<field name="user_id" ref="my_demo_app_user" />
4646
</record>
47+
48+
<record id="fastapi_endpoint_multislash_demo" model="fastapi.endpoint">
49+
<field name="name">Fastapi Multi-Slash Demo Endpoint</field>
50+
<field name="description">
51+
Like the other demo endpoint but with multi-slash
52+
</field>
53+
<field name="app">demo</field>
54+
<field name="root_path">/fastapi/demo</field>
55+
<field name="demo_auth_method">http_basic</field>
56+
<field name="user_id" ref="my_demo_app_user" />
57+
</record>
4758
</odoo>

fastapi/models/fastapi_endpoint.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,17 @@ def _reset_app_cache_marker(self):
213213
@api.model
214214
@tools.ormcache("path")
215215
def get_endpoint(self, path):
216-
root_path = "/" + path.split("/")[1]
217-
endpoint = self.search([("root_path", "=", root_path)])[:1] or False
216+
# try to match the request url with the most similar endpoint
217+
endpoints_by_length = self.search([]).sorted(
218+
lambda fe: len(fe.root_path), reverse=True
219+
)
220+
endpoint = False
221+
while endpoints_by_length:
222+
candidate_endpoint = endpoints_by_length[0]
223+
if path.startswith(candidate_endpoint.root_path):
224+
endpoint = candidate_endpoint
225+
break
226+
endpoints_by_length -= candidate_endpoint
218227
return endpoint
219228

220229
@api.model

fastapi/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
from . import test_fastapi
22
from . import test_fastapi_demo
3+
from . import test_fastapi_multislash_demo
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# License LGPL-3.0 or later (http://www.gnu.org/licenses/LGPL).
2+
3+
4+
from requests import Response
5+
6+
from fastapi import status
7+
8+
from ..routers import demo_router
9+
from .common import FastAPITransactionCase
10+
11+
12+
class FastAPIMultiSlashDemoCase(FastAPITransactionCase):
13+
"""
14+
This test verifies that multi-slash endpoint are properly reached
15+
"""
16+
17+
@classmethod
18+
def setUpClass(cls) -> None:
19+
super().setUpClass()
20+
cls.default_fastapi_router = demo_router
21+
cls.default_fastapi_running_user = cls.env.ref(
22+
"fastapi.fastapi_endpoint_multislash_demo"
23+
)
24+
cls.default_fastapi_authenticated_partner = cls.env["res.partner"].create(
25+
{"name": "FastAPI Demo"}
26+
)
27+
28+
def test_hello_world(self) -> None:
29+
with self._create_test_client() as test_client:
30+
response: Response = test_client.get("/demo/")
31+
self.assertEqual(response.status_code, status.HTTP_200_OK)
32+
self.assertDictEqual(response.json(), {"Hello": "World"})

0 commit comments

Comments
 (0)