先前在博客中分享了如何在odoo中引入fastapi,参考文章:odoo中使用FastAPI。今天记录下笔者使用 fastapi 的编码方式——直接在 fastapi 插件中进行编码。fastapi插件目录如下图所示:

一、在routers文件夹中新建自定义router文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from typing import Annotated

from odoo.api import Environment
from odoo.exceptions import AccessError, MissingError, UserError, ValidationError

from odoo.addons.base.models.res_partner import Partner

from fastapi import APIRouter, Depends, HTTPException, status

from ..dependencies import authenticated_partner, fastapi_endpoint, odoo_env
from ..models import FastapiEndpoint
from ..schemas import DemoEndpointAppInfo, DemoExceptionType, DemoUserInfo, PartnerInfo,WeixinInfo,CommonResponse

import base64
import requests
import json
import pytz
from datetime import datetime, timedelta

router = APIRouter(tags=["chinacare"])

@router.get("/partners", response_model=list[PartnerInfo])
def get_partners(env: Annotated[Environment, Depends(odoo_env)]) -> list[PartnerInfo]:
    return [
        PartnerInfo(name=partner.name, email=partner.email if partner.email else '')
        for partner in env["res.partner"].search([])
    ]

我们参考 demo 的 router 命名格式,将文件命名为 chinacare_router.py ,文件中的代码如上所示。在代码中添加一个自定义路由 /partners ,路由方法返回联系人信息。并在 __init__.py 文件中添加一行引用代码,如下所示:

1
from .chinacare_router import router as chinacare_router

二、在models文件夹中新建自定义的endpoint文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from typing import Annotated, Any, List

from odoo import _, api, fields, models
from odoo.api import Environment
from odoo.exceptions import ValidationError

from odoo.addons.base.models.res_partner import Partner

from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import APIKeyHeader

from ..dependencies import (
    authenticated_partner_from_basic_auth_user,
    authenticated_partner_impl,
    odoo_env,
)
from ..routers import chinacare_router


class FastapiEndpoint(models.Model):

    _inherit = "fastapi.endpoint"

    app: str = fields.Selection(
        selection_add=[("chinacare", "Chinacare Endpoint")], ondelete={"chinacare": "cascade"}
    )
   
    def _get_fastapi_routers(self) -> List[APIRouter]:
        if self.app == "chinacare":
            return [chinacare_router]
        return super()._get_fastapi_routers()

我们同样参考 demo 的 endpoint 命名格式,将文件命名为 fastapi_endpoint_chinacare.py ,文件中的代码如上所示。模型需要继承 fastapi.endpoint ,在 app 字段中声明应用,并在 _get_fastapi_routers 方法中将步骤一中定义的 router 挂载到 app 应用中。并在 __init__.py 文件中添加一行引用代码,如下所示:

1
from . import fastapi_endpoint_chinacare

三、配置 FastAPI Endpoint 数据

在 FastAPI Endpoint 中添加一条新数据,选择我们声明的 App 应用,配置 Root Path【注意:只能为一级,不能配置为 /chinacare/api 这样的多级模式】, 选择用户,激活之后,即可访问接口说明文档,如下图所示:

作者 菜园君