mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-18 09:12:03 +02:00
Initial commit: OCA Technical packages (595 packages)
This commit is contained in:
commit
2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions
|
|
@ -0,0 +1,143 @@
|
|||
# Copyright 2023 ACSONE SA/NV
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/LGPL).
|
||||
"""
|
||||
The demo router is a router that demonstrates how to use the fastapi
|
||||
integration with odoo.
|
||||
"""
|
||||
from typing import Annotated
|
||||
|
||||
from psycopg2 import errorcodes
|
||||
from psycopg2.errors import OperationalError
|
||||
|
||||
from odoo.api import Environment
|
||||
from odoo.exceptions import AccessError, MissingError, UserError, ValidationError
|
||||
from odoo.service.model import MAX_TRIES_ON_CONCURRENCY_FAILURE
|
||||
|
||||
from odoo.addons.base.models.res_partner import Partner
|
||||
|
||||
from fastapi import APIRouter, Depends, File, HTTPException, Query, status
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from ..dependencies import authenticated_partner, fastapi_endpoint, odoo_env
|
||||
from ..models import FastapiEndpoint
|
||||
from ..schemas import DemoEndpointAppInfo, DemoExceptionType, DemoUserInfo
|
||||
|
||||
router = APIRouter(tags=["demo"])
|
||||
|
||||
|
||||
@router.get("/demo")
|
||||
async def hello_word():
|
||||
"""Hello World!"""
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@router.get("/demo/exception")
|
||||
async def exception(exception_type: DemoExceptionType, error_message: str):
|
||||
"""Raise an exception
|
||||
|
||||
This method is used in the test suite to check that any exception
|
||||
is correctly handled by the fastapi endpoint and that the transaction
|
||||
is roll backed.
|
||||
"""
|
||||
exception_classes = {
|
||||
DemoExceptionType.user_error: UserError,
|
||||
DemoExceptionType.validation_error: ValidationError,
|
||||
DemoExceptionType.access_error: AccessError,
|
||||
DemoExceptionType.missing_error: MissingError,
|
||||
DemoExceptionType.http_exception: HTTPException,
|
||||
DemoExceptionType.bare_exception: NotImplementedError,
|
||||
}
|
||||
exception_cls = exception_classes[exception_type]
|
||||
if exception_cls is HTTPException:
|
||||
raise exception_cls(status_code=status.HTTP_409_CONFLICT, detail=error_message)
|
||||
raise exception_classes[exception_type](error_message)
|
||||
|
||||
|
||||
@router.get("/demo/lang")
|
||||
async def get_lang(env: Annotated[Environment, Depends(odoo_env)]):
|
||||
"""Returns the language according to the available languages in Odoo and the
|
||||
Accept-Language header.
|
||||
|
||||
This method is used in the test suite to check that the language is correctly
|
||||
set in the Odoo environment according to the Accept-Language header
|
||||
"""
|
||||
return env.context.get("lang")
|
||||
|
||||
|
||||
@router.get("/demo/who_ami")
|
||||
async def who_ami(
|
||||
partner: Annotated[Partner, Depends(authenticated_partner)]
|
||||
) -> DemoUserInfo:
|
||||
"""Who am I?
|
||||
|
||||
Returns the authenticated partner
|
||||
"""
|
||||
# This method show you how you can rget the authenticated partner without
|
||||
# depending on a specific implementation.
|
||||
return DemoUserInfo(name=partner.name, display_name=partner.display_name)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/demo/endpoint_app_info",
|
||||
dependencies=[Depends(authenticated_partner)],
|
||||
)
|
||||
async def endpoint_app_info(
|
||||
endpoint: Annotated[FastapiEndpoint, Depends(fastapi_endpoint)],
|
||||
) -> DemoEndpointAppInfo:
|
||||
"""Returns the current endpoint configuration"""
|
||||
# This method show you how to get access to current endpoint configuration
|
||||
# It also show you how you can specify a dependency to force the security
|
||||
# even if the method doesn't require the authenticated partner as parameter
|
||||
return DemoEndpointAppInfo.model_validate(endpoint)
|
||||
|
||||
|
||||
_CPT = 0
|
||||
|
||||
|
||||
@router.get("/demo/retrying")
|
||||
async def retrying(
|
||||
nbr_retries: Annotated[int, Query(gt=1, lt=MAX_TRIES_ON_CONCURRENCY_FAILURE)],
|
||||
) -> int:
|
||||
"""This method is used in the test suite to check that the retrying
|
||||
functionality in case of concurrency error on the database is working
|
||||
correctly for retryable exceptions.
|
||||
|
||||
The output will be the number of retries that have been done.
|
||||
|
||||
This method is mainly used to test the retrying functionality
|
||||
"""
|
||||
global _CPT
|
||||
if _CPT < nbr_retries:
|
||||
_CPT += 1
|
||||
raise FakeConcurrentUpdateError("fake error")
|
||||
tryno = _CPT
|
||||
_CPT = 0
|
||||
return tryno
|
||||
|
||||
|
||||
@router.post("/demo/retrying")
|
||||
async def retrying_post(
|
||||
nbr_retries: Annotated[int, Query(gt=1, lt=MAX_TRIES_ON_CONCURRENCY_FAILURE)],
|
||||
file: Annotated[bytes, File()],
|
||||
) -> JSONResponse:
|
||||
"""This method is used in the test suite to check that the retrying
|
||||
functionality in case of concurrency error on the database is working
|
||||
correctly for retryable exceptions.
|
||||
|
||||
The output will be the number of retries that have been done.
|
||||
|
||||
This method is mainly used to test the retrying functionality
|
||||
"""
|
||||
global _CPT
|
||||
if _CPT < nbr_retries:
|
||||
_CPT += 1
|
||||
raise FakeConcurrentUpdateError("fake error")
|
||||
tryno = _CPT
|
||||
_CPT = 0
|
||||
return JSONResponse(content={"retries": tryno, "file": file.decode("utf-8")})
|
||||
|
||||
|
||||
class FakeConcurrentUpdateError(OperationalError):
|
||||
@property
|
||||
def pgcode(self):
|
||||
return errorcodes.SERIALIZATION_FAILURE
|
||||
Loading…
Add table
Add a link
Reference in a new issue