python 服务自动生成 js 调用
python 服务自动生成 js 调用
原理
- 接管请求分发过程; 为每个 command 维护对应的 handler;
- 利用 python 动态特性, 获得 handler 的参数;
- 利用模版生成 js 代码;
- 利用**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)