Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIG] base_rest, base_rest_auth_api_key, base_rest_datamodel, base_rest_demo, base_rest_pydantic, datamodel, extendable: Migration to 16.0 #313

Merged
merged 6 commits into from
Jan 26, 2023
Merged
Show file tree
Hide file tree
Changes from 5 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
8 changes: 0 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
exclude: |
(?x)
# NOT INSTALLABLE ADDONS
^base_rest/|
^base_rest_auth_api_key/|
^base_rest_auth_jwt/|
^base_rest_auth_user_service/|
^base_rest_datamodel/|
^base_rest_demo/|
^base_rest_pydantic/|
^datamodel/|
^extendable/|
^model_serializer/|
^pydantic/|
^rest_log/|
# END NOT INSTALLABLE ADDONS
# Files and folders generated by bots, to avoid loops
Expand Down
7 changes: 7 additions & 0 deletions base_rest/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import logging
from . import models
from . import components
from . import http

logging.getLogger(__file__).warning(
"base_rest is deprecated and not fully supported anymore on Odoo 16. "
"Please migrate to the FastAPI migration module. "
"See https://github.com/OCA/rest-framework/pull/291.",
)
13 changes: 7 additions & 6 deletions base_rest/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,32 @@
"summary": """
Develop your own high level REST APIs for Odoo thanks to this addon.
""",
"version": "15.0.1.2.0",
"version": "16.0.1.0.0",
"development_status": "Beta",
"license": "LGPL-3",
"author": "ACSONE SA/NV, " "Odoo Community Association (OCA)",
"maintainers": ["lmignon"],
Copy link
Member

@FrancoMaxime FrancoMaxime Jan 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lmignon, as you requested you have been removed from the list of maintainers for this module. Maybe you would like to be removed from other modules like base_rest_demo?

"maintainers": [],
"website": "https://github.com/OCA/rest-framework",
"depends": ["component", "web"],
"data": [
"views/openapi_template.xml",
"views/base_rest_view.xml",
],
"assets": {
"web.assets_common": [
"web.assets_frontend": [
"base_rest/static/src/scss/base_rest.scss",
"base_rest/static/src/js/swagger_ui.js",
"base_rest/static/src/js/swagger.js",
],
},
"demo": [],
"external_dependencies": {
"python": [
"cerberus",
"pyquerystring",
"parse-accept-language",
"apispec>=4.0.0",
# adding version causes missing-manifest-dependency false positives
"apispec",
]
},
"installable": False,
"installable": True,
}
7 changes: 4 additions & 3 deletions base_rest/apispec/base_rest_service_apispec.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from apispec import APISpec

from ..core import _rest_services_databases
from ..tools import ROUTING_DECORATOR_ATTR
from .rest_method_param_plugin import RestMethodParamPlugin
from .rest_method_security_plugin import RestMethodSecurityPlugin
from .restapi_method_route_plugin import RestApiMethodRoutePlugin
Expand Down Expand Up @@ -62,18 +63,18 @@ def _get_plugins(self):

def _add_method_path(self, method):
description = textwrap.dedent(method.__doc__ or "")
routing = method.routing
routing = getattr(method, ROUTING_DECORATOR_ATTR)
for paths, method in routing["routes"]:
for path in paths:
self.path(
path,
operations={method.lower(): {"summary": description}},
routing=routing,
**{ROUTING_DECORATOR_ATTR: routing},
)

def generate_paths(self):
for _name, method in inspect.getmembers(self._service, inspect.ismethod):
routing = getattr(method, "routing", None)
routing = getattr(method, ROUTING_DECORATOR_ATTR, None)
if not routing:
continue
self._add_method_path(method)
7 changes: 4 additions & 3 deletions base_rest/apispec/rest_method_param_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from apispec import BasePlugin

from ..restapi import RestMethodParam
from ..tools import ROUTING_DECORATOR_ATTR


class RestMethodParamPlugin(BasePlugin):
Expand All @@ -25,22 +26,22 @@ def init_spec(self, spec):
self.openapi_version = spec.openapi_version

def operation_helper(self, path=None, operations=None, **kwargs):
routing = kwargs.get("routing")
routing = kwargs.get(ROUTING_DECORATOR_ATTR)
if not routing:
super(RestMethodParamPlugin, self).operation_helper(
path, operations, **kwargs
)
if not operations:
return
for method, params in operations.items():
parameters = self._generate_pamareters(routing, method, params)
parameters = self._generate_parameters(routing, method, params)
if parameters:
params["parameters"] = parameters
responses = self._generate_responses(routing, method, params)
if responses:
params["responses"] = responses

def _generate_pamareters(self, routing, method, params):
def _generate_parameters(self, routing, method, params):
parameters = params.get("parameters", [])
# add default paramters provided by the sevice
parameters.extend(self._default_parameters)
Expand Down
4 changes: 3 additions & 1 deletion base_rest/apispec/rest_method_security_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

from apispec import BasePlugin

from ..tools import ROUTING_DECORATOR_ATTR


class RestMethodSecurityPlugin(BasePlugin):
"""
Expand All @@ -23,7 +25,7 @@ def init_spec(self, spec):
spec.components.security_scheme("user", user_scheme)

def operation_helper(self, path=None, operations=None, **kwargs):
routing = kwargs.get("routing")
routing = kwargs.get(ROUTING_DECORATOR_ATTR)
if not routing:
super(RestMethodSecurityPlugin, self).operation_helper(
path, operations, **kwargs
Expand Down
5 changes: 3 additions & 2 deletions base_rest/components/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from odoo.addons.component.core import AbstractComponent

from ..apispec.base_rest_service_apispec import BaseRestServiceAPISpec
from ..tools import ROUTING_DECORATOR_ATTR

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -93,7 +94,7 @@ def _prepare_input_params(self, method, params):
method_name = method.__name__
if hasattr(method, "skip_secure_params"):
return params
routing = getattr(method, "routing", None)
routing = getattr(method, ROUTING_DECORATOR_ATTR, None)
if not routing:
_logger.warning(
"Method %s is not a public method of service %s",
Expand Down Expand Up @@ -122,7 +123,7 @@ def _prepare_response(self, method, result):
method_name = method.__name__
if hasattr(method, "skip_secure_response"):
return result
routing = getattr(method, "routing", None)
routing = getattr(method, ROUTING_DECORATOR_ATTR, None)
output_param = routing["output_param"]
if not output_param:
_logger.warning(
Expand Down
72 changes: 34 additions & 38 deletions base_rest/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from werkzeug.exceptions import BadRequest

from odoo import models
from odoo.http import Controller, ControllerType, Response, request
from odoo.http import Controller, Response, request

from odoo.addons.component.core import WorkContext, _get_addon_name

Expand All @@ -25,43 +25,7 @@ def __init__(self, name, env):
self.id = None


class RestControllerType(ControllerType):

# pylint: disable=E0213
def __init__(cls, name, bases, attrs): # noqa: B902
if (
"RestController" in globals()
and RestController in bases
and Controller not in bases
):
# to be registered as a controller into the ControllerType,
# our RestConrtroller must be a direct child of Controller
bases += (Controller,)
super(RestControllerType, cls).__init__(name, bases, attrs)
if "RestController" not in globals() or not any(
issubclass(b, RestController) for b in bases
):
return
# register the rest controller into the rest controllers registry
root_path = getattr(cls, "_root_path", None)
collection_name = getattr(cls, "_collection_name", None)
if root_path and collection_name:
cls._module = _get_addon_name(cls.__module__)
_rest_controllers_per_module[cls._module].append(
{
"root_path": root_path,
"collection_name": collection_name,
"controller_class": cls,
}
)
_logger.debug(
"Added rest controller %s for module %s",
_rest_controllers_per_module[cls._module][-1],
cls._module,
)


class RestController(Controller, metaclass=RestControllerType):
class RestController(Controller):
"""Generic REST Controller

This controller is the base controller used by as base controller for all the REST
Expand Down Expand Up @@ -130,6 +94,38 @@ class ControllerB(ControllerB):

_component_context_provider = "component_context_provider"

@classmethod
def __init_subclass__(cls):
if (
"RestController" in globals()
and RestController in cls.__bases__
and Controller not in cls.__bases__
):
# Ensure that Controller's __init_subclass__ kicks in.
cls.__bases__ += (Controller,)
super().__init_subclass__()
if "RestController" not in globals() or not any(
issubclass(b, RestController) for b in cls.__bases__
):
return
# register the rest controller into the rest controllers registry
root_path = getattr(cls, "_root_path", None)
collection_name = getattr(cls, "_collection_name", None)
if root_path and collection_name:
cls._module = _get_addon_name(cls.__module__)
_rest_controllers_per_module[cls._module].append(
{
"root_path": root_path,
"collection_name": collection_name,
"controller_class": cls,
}
)
_logger.debug(
"Added rest controller %s for module %s",
_rest_controllers_per_module[cls._module][-1],
cls._module,
)

def _get_component_context(self, collection=None):
"""
This method can be inherited to add parameter into the component
Expand Down
Loading