python 注册nacos 进行接口规范定义

背景:

一般场景 python服务经常作为java下游的 算法服务或者 数据处理服务

但是使用http 去调用比较不灵活,通过注册到nacos上进行微服务调用才是比较爽的

1.定义feginapi的接口定义

java端

定义接口请求和响应 主要关注

CommonResult 结构 和 python要一直 ,不然序列号是有问题的

CommonResult<List<SocialRelationRefDTO>> 和python的 接口的结构要一致
@FeignClient(name = ApiConstants.PYTHON_WEB_SERVER)
@Tag(name = "RPC 服务 - 调用py信息分析接口")
public interface PythonInfoAnalysisApi {

    String PREFIX = "analysis";

@PostMapping(PREFIX + "/get_article_similar_relation_ref")
CommonResult<List<SocialRelationRefDTO>> getArticleSimilarRelationRef(@RequestBody List<SocialRelationRefDTO> dto);
}
CommonResult 结构

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.util.Objects;

/**
 * 通用返回
 *
 * @param <T> 数据泛型
 */
@Data
public class CommonResult<T> implements Serializable {

    /**
     * 错误码
     *
     * @see ErrorCode#getCode()
     */
    private Integer code;
    /**
     * 返回数据
     */
    private T data;
    /**
     * 错误提示,用户可阅读
     *
     * @see ErrorCode#getMsg() ()
     */
    private String msg;

    /**
     * 将传入的 result 对象,转换成另外一个泛型结果的对象
     *
     * 因为 A 方法返回的 CommonResult 对象,不满足调用其的 B 方法的返回,所以需要进行转换。
     *
     * @param result 传入的 result 对象
     * @param <T>    返回的泛型
     * @return 新的 CommonResult 对象
     */
    public static <T> CommonResult<T> error(CommonResult<?> result) {
        return error(result.getCode(), result.getMsg());
    }

    public static <T> CommonResult<T> error(Integer code, String message) {
        Assert.isTrue(!GlobalErrorCodeConstants.SUCCESS.getCode().equals(code), "code 必须是错误的!");
        CommonResult<T> result = new CommonResult<>();
        result.code = code;
        result.msg = message;
        return result;
    }

    public static <T> CommonResult<T> error(ErrorCode errorCode) {
        return error(errorCode.getCode(), errorCode.getMsg());
    }

    public static <T> CommonResult<T> success(T data) {
        CommonResult<T> result = new CommonResult<>();
        result.code = GlobalErrorCodeConstants.SUCCESS.getCode();
        result.data = data;
        result.msg = "success";
        return result;
    }

    public static boolean isSuccess(Integer code) {
        return Objects.equals(code, GlobalErrorCodeConstants.SUCCESS.getCode());
    }

    @JsonIgnore // 避免 jackson 序列化
    public boolean isSuccess() {
        return isSuccess(code);
    }

    @JsonIgnore // 避免 jackson 序列化
    public boolean isError() {
        return !isSuccess();
    }

    // ========= 和 Exception 异常体系集成 =========

    /**
     * 判断是否有异常。如果有,则抛出 {@link ServiceException} 异常
     */
    public void checkError() throws ServiceException {
        if (isSuccess()) {
            return;
        }
        // 业务异常
        throw new ServiceException(code, msg);
    }

    /**
     * 判断是否有异常。如果有,则抛出 {@link ServiceException} 异常
     * 如果没有,则返回 {@link #data} 数据
     */
    @JsonIgnore // 避免 jackson 序列化
    public T getCheckedData() {
        checkError();
        return data;
    }

    public static <T> CommonResult<T> error(ServiceException serviceException) {
        return error(serviceException.getCode(), serviceException.getMessage());
    }

}

python端

 CommonResult :结构

 1 import json
 2 from typing import TypeVar, Generic, Optional
 3 from dataclasses import dataclass
 4 
 5 from flask import jsonify
 6 
 7 T = TypeVar('T')
 8 
 9 
10 @dataclass
11 class CommonResult(Generic[T]):
12     code: Optional[int] = None
13     data: T = None
14     msg: str = None
15 
16     @staticmethod
17     def error(code: int, message: str) -> 'CommonResult':
18         assert code is not None, "code must be provided"
19         return CommonResult(code=code, msg=message)
20 
21     @staticmethod
22     def success(data: T):
23         result = CommonResult(code=0, data=data, msg="success")
24         return jsonify(result.to_dict())
25

 

36 
37     def get_checked_data(self) -> T:
38         self.check_error()
39         return self.data
40 
41     def to_dict(self):
42         return {
43             "code": self.code,
44             "data": self.data,
45             "msg": self.msg
46         }

接口端:

@analysis_controller_bp.route('/build_media_topological_graph', methods=['POST'])
def build_media_topological_graph():
    data = request.json
    result = social_relation_service.build_media_topological_graph(data)
    common_result = CommonResult.success(result)
    print(common_result)
    return common_result  # 将CommonResult转换为字典并返回JSON响应

python 启动 类加上 注册nacos和 心跳检查

 

import os
import socket
import threading
import time

import nacos
from flask import Flask
from route.route import register_route
from util.nacos_util import NacosInstance
import logging
from conf import NACOS_SERVER_ADDRESS, NACOS_SERVER_NAMESPACE

app = Flask(__name__)
app.config["JSON_AS_ASCII"] = False

client = nacos.NacosClient(NACOS_SERVER_ADDRESS, namespace=NACOS_SERVER_NAMESPACE)

hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
instance = NacosInstance(
    NACOS_SERVER_ADDRESS, namespace=NACOS_SERVER_NAMESPACE,
    service_name="python-web-server",
    instance_ip=ip_address,
    instance_port=5000,
    cluster='DEFAULT'
)


def service_register():
    # 创建 Nacos 实
    # 注册服务
    # instance.register()
    instance.register()


def heartbeat_task():
    while True:
        instance.heartbeat()
        time.sleep(5)


heartbeat_thread = threading.Thread(target=heartbeat_task)
heartbeat_thread.start()

app = Flask(__name__)

register_route(app)

if __name__ == '__main__':
    service_register()
    app.run(debug=True, host='0.0.0.0', port=5000)
    # 当应用退出时,注销服务
    deregister = instance.deregister()
    print(deregister)

python注册nacos 核心方法

 

posted @ 2024-06-18 17:53  夜半钟声到客船  阅读(25)  评论(0编辑  收藏  举报