Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 5 additions & 2 deletions fastapi/fastapi_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ def dispatch(self, endpoint, args):
self.request.params = {} # dict(self.request.get_http_params(), **args)
environ = self._get_environ()
path = environ["PATH_INFO"]
endpoint_model = request.env["fastapi.endpoint"].sudo()
# Ensure that only one app exists by endpoint's root path
root_path = endpoint_model._get_root_path(path) or path
# TODO store the env into contextvar to be used by the odoo_env
# depends method
with fastapi_app_pool.get_app(env=request.env, root_path=path) as app:
uid = request.env["fastapi.endpoint"].sudo().get_uid(path)
with fastapi_app_pool.get_app(env=request.env, root_path=root_path) as app:
uid = endpoint_model.get_uid(root_path)
data = BytesIO()
with self._manage_odoo_env(uid):
for r in app(environ, self._make_response):
Expand Down
11 changes: 11 additions & 0 deletions fastapi/models/fastapi_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,17 @@ def _get_id_for_path(self, path):
root_path = self._find_first_matching_url_path(id_by_path.keys(), path)
return id_by_path.get(root_path)

@api.model
def _get_root_path(self, path):
"""Return the root path of the endpoint that serves the given path.

Not cached on the path: a request path can contain anything, so caching
on it would keep one entry per distinct path.
"""
return self._find_first_matching_url_path(
self._get_id_by_root_path_map().keys(), path
)

@api.model
def _get_endpoint(self, path):
id_ = self._get_id_for_path(path)
Expand Down
12 changes: 12 additions & 0 deletions fastapi/tests/test_fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from fastapi import status

from ..pools import fastapi_app_pool
from ..schemas import DemoExceptionType


Expand Down Expand Up @@ -195,6 +196,17 @@ def test_url_matching(self):
"/fastapi/v1",
)

def test_app_pool_keyed_on_root_path(self):
# Calls to endpoints under the same root path are processed by the same
# app: only one app is initialized by root path
for route in ("/fastapi_demo/demo", "/fastapi_demo/demo/lang"):
response = self.url_open(route, timeout=20)
self.assertEqual(response.status_code, 200)
pools = fastapi_app_pool._queue_by_db_by_root_path[self.env.cr.dbname]
self.assertIn(self.fastapi_demo_app.root_path, pools)
self.assertNotIn("/fastapi_demo/demo", pools)
self.assertNotIn("/fastapi_demo/demo/lang", pools)

def test_multi_slash(self):
route = "/fastapi/demo-multi/demo/"
response = self.url_open(route, timeout=20)
Expand Down
Loading