From 709c1d81ceac224f7a6d26b019b1e8162657c169 Mon Sep 17 00:00:00 2001 From: Danilo Moya Date: Sun, 11 Oct 2026 21:51:38 -0500 Subject: [PATCH] [20.0][MIG] fastapi: Migration to 20.0 --- .pre-commit-config.yaml | 6 ++ fastapi/README.rst | 14 +++-- fastapi/__manifest__.py | 12 ++-- fastapi/demo/fastapi_endpoint_demo.xml | 4 +- fastapi/depends.py | 2 +- fastapi/fastapi_dispatcher.py | 7 ++- fastapi/models/fastapi_endpoint.py | 15 ++--- fastapi/models/ir_rule.py | 17 ++---- fastapi/models/res_lang.py | 4 +- fastapi/patch.py | 34 +++++++++++- fastapi/pools/fastapi_app.py | 7 ++- fastapi/readme/CONTRIBUTORS.md | 2 + fastapi/routers/demo_router.py | 9 ++- fastapi/security/fastapi_endpoint.xml | 24 -------- fastapi/security/ir.access.csv | 6 ++ fastapi/security/ir_rule+acl.xml | 73 ------------------------- fastapi/security/res_groups.xml | 8 +-- fastapi/static/description/index.html | 13 +++-- fastapi/tests/common.py | 5 +- fastapi/tests/test_db_param.py | 59 +++++++++++++++----- fastapi/tests/test_fastapi_demo.py | 42 +++++++------- fastapi/views/fastapi_endpoint.xml | 14 ++--- fastapi/views/fastapi_endpoint_demo.xml | 4 +- fastapi/views/fastapi_menu.xml | 2 +- 24 files changed, 188 insertions(+), 195 deletions(-) delete mode 100644 fastapi/security/fastapi_endpoint.xml create mode 100644 fastapi/security/ir.access.csv delete mode 100644 fastapi/security/ir_rule+acl.xml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3343f3b27..077d5b13f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,12 @@ exclude: | (?x) # NOT INSTALLABLE ADDONS + ^base_rest/| + ^base_rest_auth_api_key/| + ^base_rest_pydantic/| + ^extendable/| + ^pydantic/| + ^rest_log/| # END NOT INSTALLABLE ADDONS # Files and folders generated by bots, to avoid loops ^setup/|/static/description/index\.html$| diff --git a/fastapi/README.rst b/fastapi/README.rst index b1848be3f..481bcc702 100644 --- a/fastapi/README.rst +++ b/fastapi/README.rst @@ -21,13 +21,13 @@ Odoo FastAPI :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Frest--framework-lightgray.png?logo=github - :target: https://github.com/OCA/rest-framework/tree/19.0/fastapi + :target: https://github.com/OCA/rest-framework/tree/20.0/fastapi :alt: OCA/rest-framework .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/rest-framework-19-0/rest-framework-19-0-fastapi + :target: https://translation.odoo-community.org/projects/rest-framework-20-0/rest-framework-20-0-fastapi :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/rest-framework&target_branch=19.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/rest-framework&target_branch=20.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -1636,7 +1636,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -1647,12 +1647,16 @@ Authors ------- * ACSONE SA/NV +* Open2S Contributors ------------ - Laurent Mignon - Lois Rilo +- Open2S (https://www.open2s.com.ec): + + - Danilo Moya Maintainers ----------- @@ -1675,6 +1679,6 @@ Current `maintainer `__: |maintainer-lmignon| -This module is part of the `OCA/rest-framework `_ project on GitHub. +This module is part of the `OCA/rest-framework `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/fastapi/__manifest__.py b/fastapi/__manifest__.py index 85928f7b5..0ac9ed2ac 100644 --- a/fastapi/__manifest__.py +++ b/fastapi/__manifest__.py @@ -3,18 +3,16 @@ { "name": "Odoo FastAPI", - "summary": """ - Odoo FastAPI endpoint""", - "version": "19.0.1.1.0", + "summary": "Odoo FastAPI endpoint", + "version": "20.0.1.1.0", "license": "LGPL-3", - "author": "ACSONE SA/NV,Odoo Community Association (OCA)", + "author": "ACSONE SA/NV, Open2S, Odoo Community Association (OCA)", "maintainers": ["lmignon"], "website": "https://github.com/OCA/rest-framework", "depends": ["endpoint_route_handler"], "data": [ "security/res_groups.xml", - "security/fastapi_endpoint.xml", - "security/ir_rule+acl.xml", + "security/ir.access.csv", "views/fastapi_menu.xml", "views/fastapi_endpoint.xml", "views/fastapi_endpoint_demo.xml", @@ -30,5 +28,5 @@ ] }, "development_status": "Beta", - "installable": False, + "installable": True, } diff --git a/fastapi/demo/fastapi_endpoint_demo.xml b/fastapi/demo/fastapi_endpoint_demo.xml index 1b9b13732..a3087f02e 100644 --- a/fastapi/demo/fastapi_endpoint_demo.xml +++ b/fastapi/demo/fastapi_endpoint_demo.xml @@ -1,4 +1,4 @@ - + @@ -31,7 +31,7 @@ This endpoint will be registered on the "/fastapi_demo" path --> - + Fastapi Demo Endpoint bool: path = self._normalize_url_path(path) prefix = self._normalize_url_path(prefix) - if path == prefix: - return True - if path.startswith(prefix + "/"): - return True - return False + return path == prefix or bool(path.startswith(prefix + "/")) @api.model def _find_first_matching_url_path(self, paths, prefix) -> str | None: @@ -296,7 +291,7 @@ def _clear_fastapi_exception_handlers(self, app: FastAPI) -> None: self._clear_fastapi_exception_handlers(route.app) @api.model - @tools.ormcache("path") + @api.ormcache("path") def get_uid(self, path): record = self._get_endpoint(path) if not record: diff --git a/fastapi/models/ir_rule.py b/fastapi/models/ir_rule.py index 68bda16f6..0c47d0196 100644 --- a/fastapi/models/ir_rule.py +++ b/fastapi/models/ir_rule.py @@ -4,15 +4,10 @@ from odoo import api, models -class IrRule(models.Model): - """Add authenticated_partner_id in record rule evaluation context. +class IrAccess(models.Model): + """Add authenticated_partner_id in record rule/access evaluation context.""" - This come from the env current odoo environment which is - populated by dependency method authenticated_partner_env or authenticated_partner - when a route handler depends one of them and is called by the FastAPI service layer. - """ - - _inherit = "ir.rule" + _inherit = "ir.access" @api.model def _eval_context(self): @@ -22,6 +17,6 @@ def _eval_context(self): ) return ctx - def _compute_domain_keys(self): - """Return the list of context keys to use for caching ``_compute_domain``.""" - return super()._compute_domain_keys() + ["authenticated_partner_id"] + def _get_access_context(self): + yield from super()._get_access_context() + yield self.env.context.get("authenticated_partner_id") diff --git a/fastapi/models/res_lang.py b/fastapi/models/res_lang.py index 55453c405..f8c66d3d6 100644 --- a/fastapi/models/res_lang.py +++ b/fastapi/models/res_lang.py @@ -5,14 +5,14 @@ from accept_language import parse_accept_language -from odoo import api, models, tools +from odoo import api, models class ResLang(models.Model): _inherit = "res.lang" @api.model - @tools.ormcache("accept_language") + @api.ormcache("accept_language") def _get_lang_from_accept_language(self, accept_language): """Get the language from the Accept-Language header. diff --git a/fastapi/patch.py b/fastapi/patch.py index 7904e46aa..7fc17980c 100644 --- a/fastapi/patch.py +++ b/fastapi/patch.py @@ -3,9 +3,18 @@ from urllib.parse import parse_qs, urlparse -from odoo.http import Request, db_filter +try: + import odoo.http.router as http_router + from odoo.http.requestlib import Request + from odoo.http.router import db_filter +except ImportError: + http_router = None + from odoo.http import Request, db_filter -_original_get_session_and_dbname = Request._get_session_and_dbname +_original_set_session_and_dbname = ( + getattr(http_router, "_set_session_and_dbname", None) if http_router else None +) +_original_get_session_and_dbname = getattr(Request, "_get_session_and_dbname", None) def _patched_get_session_and_dbname(self): @@ -28,4 +37,23 @@ def _patched_get_session_and_dbname(self): return session, dbname -Request._get_session_and_dbname = _patched_get_session_and_dbname +def _patched_set_session_and_dbname(request): + _original_set_session_and_dbname(request) + if not getattr(request, "db", None): + db = request.httprequest.args.get("db", "").strip() + if not db: + referer = request.httprequest.headers.get("Referer", "") + if referer: + parsed = urlparse(referer) + db = parse_qs(parsed.query).get("db", [""])[0].strip() + host = request.httprequest.environ.get("HTTP_HOST", "") + if db and db_filter([db], host=host): + request.db = db + if hasattr(request, "session") and request.session: + request.session.db = db + + +if _original_set_session_and_dbname is not None: + http_router._set_session_and_dbname = _patched_set_session_and_dbname +elif _original_get_session_and_dbname is not None: + Request._get_session_and_dbname = _patched_get_session_and_dbname diff --git a/fastapi/pools/fastapi_app.py b/fastapi/pools/fastapi_app.py index 9e04fe011..ef14a3f61 100644 --- a/fastapi/pools/fastapi_app.py +++ b/fastapi/pools/fastapi_app.py @@ -114,7 +114,12 @@ def set_cache_sequence(self, key: str, value: int) -> None: self.__cache_sequences[key] = value def _check_cache(self, env: Environment) -> None: - cache_sequences = env.registry.cache_sequences + cache_sequences = getattr(env.registry, "cache_sequences", None) + if cache_sequences is None: + cache_sequences = { + k: v[0] + for k, v in getattr(env.registry, "registry_caches__", {}).items() + } for key, value in cache_sequences.items(): if ( value != self.get_cache_sequence(key) diff --git a/fastapi/readme/CONTRIBUTORS.md b/fastapi/readme/CONTRIBUTORS.md index bdbfd97ff..83d6e08e7 100644 --- a/fastapi/readme/CONTRIBUTORS.md +++ b/fastapi/readme/CONTRIBUTORS.md @@ -1,2 +1,4 @@ - Laurent Mignon \<\> - Lois Rilo \<\> +- Open2S (https://www.open2s.com.ec): + - Danilo Moya \<\> diff --git a/fastapi/routers/demo_router.py b/fastapi/routers/demo_router.py index a3b94aa10..fccb81b08 100644 --- a/fastapi/routers/demo_router.py +++ b/fastapi/routers/demo_router.py @@ -12,7 +12,14 @@ from odoo.api import Environment from odoo.exceptions import AccessError, MissingError, UserError, ValidationError -from odoo.service.model import MAX_TRIES_ON_CONCURRENCY_FAILURE + +try: + from odoo.http.retrying import MAX_TRIES_ON_CONCURRENCY_FAILURE +except ImportError: + try: + from odoo.service.model import MAX_TRIES_ON_CONCURRENCY_FAILURE + except ImportError: + MAX_TRIES_ON_CONCURRENCY_FAILURE = 5 from odoo.addons.base.models.res_partner import ResPartner diff --git a/fastapi/security/fastapi_endpoint.xml b/fastapi/security/fastapi_endpoint.xml deleted file mode 100644 index 1bb23ac5d..000000000 --- a/fastapi/security/fastapi_endpoint.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - fastapi.endpoint view - - - - - - - - - - fastapi.endpoint manage - - - - - - - - diff --git a/fastapi/security/ir.access.csv b/fastapi/security/ir.access.csv new file mode 100644 index 000000000..26addf867 --- /dev/null +++ b/fastapi/security/ir.access.csv @@ -0,0 +1,6 @@ +id,name,model_id,group_id/id,operation,domain +res_user_fastapi_running_user,Fastapi: Running user read users,res.users,fastapi.group_fastapi_endpoint_runner,r,"[('id', '=', user.id)]" +res_partner_fastapi_running_user,Fastapi: Running user read partners,res.partner,fastapi.group_fastapi_endpoint_runner,r,"['|', ('user_ids', '=', user.id), ('id', '=', authenticated_partner_id)]" +fastapi_endpoint_fastapi_running_user,Fastapi: Running user read endpoints,fastapi.endpoint,fastapi.group_fastapi_endpoint_runner,r,"[('user_id', '=', user.id)]" +fastapi_endpoint_access_view,fastapi.endpoint view,fastapi.endpoint,fastapi.group_fastapi_user,r, +fastapi_endpoint_access_manage,fastapi.endpoint manage,fastapi.endpoint,fastapi.group_fastapi_manager,crud, diff --git a/fastapi/security/ir_rule+acl.xml b/fastapi/security/ir_rule+acl.xml deleted file mode 100644 index 99b06ce56..000000000 --- a/fastapi/security/ir_rule+acl.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - Fastapi: Running user read users - - - - - - - - - - - Fastapi: Running user rule - - [('id', '=', user.id)] - - - - - - Fastapi: Running user read partners - - - - - - - - - - - Fastapi: Running user rule - - ['|', ('user_ids', '=', user.id), ('id', '=', authenticated_partner_id)] - - - - - - Fastapi: Running user read endpoints - - - - - - - - - - - Fastapi: Running user rule - - [('user_id', '=', user.id)] - - - diff --git a/fastapi/security/res_groups.xml b/fastapi/security/res_groups.xml index 7043ea69f..08492c107 100644 --- a/fastapi/security/res_groups.xml +++ b/fastapi/security/res_groups.xml @@ -1,17 +1,17 @@ - + - + FastAPI Helps you manage your Fastapi Endpoints - 99 + FastAPI - 99 + diff --git a/fastapi/static/description/index.html b/fastapi/static/description/index.html index 3abdf612f..84ac075f4 100644 --- a/fastapi/static/description/index.html +++ b/fastapi/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Odoo FastAPI