python 服务自动生成 js 调用

python 服务自动生成 js 调用

原理

  1. 接管请求分发过程; 为每个 command 维护对应的 handler;
  2. 利用 python 动态特性, 获得 handler 的参数;
  3. 利用模版生成 js 代码;
  4. 利用**kwargs 获取所有参数传递给 handler;

Demo

以 Flask 为例

# main.py
from flask import Flask, request
from dispatch import dispath, get_command, command_map
from js_stub import gen_js_file

app = Flask(__name__)


@app.route("/command/<command_name>", methods=['POST'])
def add(command_name):
    j = request.get_json()
    command = get_command(command_name)
    print(command(**j))
    return {
        "command": command_name,
        "result": command(**j),
    }


@dispath("add")
def _(a, b):
    return a+b


@dispath("minus")
def _(a, b):
    return a-b


if __name__ == '__main__':
    gen_js_file(command_map)
    app.run(port=3000, debug=True)

生成 js 代码如下:

import axios from "axios";

const base_url = "http://127.0.0.1:3000/command";

export async function add(a, b) {
  const r = await axios.post(`${base_url}/add`, { a, b });
  return r.data.result;
}

export async function minus(a, b) {
  const r = await axios.post(`${base_url}/minus`, { a, b });
  return r.data.result;
}

实现如下

# dispatch.py
command_map = {}


def dispath(command_name):
    def outer(func):
        command_map[command_name] = func
        return func
    return outer

def get_command(command_name):
    return command_map[command_name]
# js_stub.py


template = """
async function(){
    return axios.post('')
}
"""
base_url = "http://127.0.0.1:5000/command"


def gen_func(command_name, func):
    vars = ",".join(func.__code__.co_varnames)
    return f"""export async function {command_name}({vars}) {{
    const r = await axios.post(`${{base_url}}/{command_name}`,{{{vars}}})
    return r.data.result
}}"""


def gen_js_file(command_map):
    js_content = [
        "import axios from 'axios'",
        "const base_url='http://127.0.0.1:3000/command'"
    ]

    for command_name, func in command_map.items():
        js_content.append(gen_func(command_name, func))

    content = '\n\n'.join(js_content)
    with open('./gen/api.js', 'w') as f:
        f.write(content)

posted @ 2024-03-18 11:35  Aloe_n  阅读(7)  评论(0编辑  收藏  举报