所有编程语言调用python方式,非命令行可以获取返回值,适合所有Python版本

所有编程语言调用python方式,非命令行可以获取返回值,适合所有Python版本,第1张

目前为止,如java,go等编程语言调用python的主要方式是命令行调用或者利用python c api,jpython等方式进行调用,这些方式各有各自的缺陷,比如jpython只能试用特定python,命令行无法获得返回值等,为此我想到一个方法,及python调用python,暴露一个api,可以适合各种编程语言,切对于Python所以import都适用,直接先上代码了
from flask import request, jsonify, Flask
import importlib
import inspect
import sys
import json

app = Flask(__name__)


@app.route('/', methods=["POST"])
def run_py():  # put application's code here
    data_list = []
    data = json.loads(request.get_data(as_text=True))

    method = data["method"]
    path = data["path"]
    type = data["type"]
    args = data["args"]
    sys_path = data["sys"]
    for p in sys_path:
        sys.path.append(p)

   #moudle_name无实际作用
    spec = importlib.util.spec_from_file_location("moudle_name", path)
    odm = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(odm)
    v_list = []
    if hasattr(odm, method):
        func = getattr(odm, method)
        v_list = []
        r = inspect.getfullargspec(func)  # 获取FullArgSpec对象
        j = 0
        for i in r.args:
            if type == "map":
                v_list.append(args[i])
            elif type == "array":
                v_list.append(args[j])
                j = j + 1
        res = func(*v_list)
        return jsonify({"code": 200, "msg": "ok", "data": res})


if __name__ == '__main__':
    app.run(host="127.0.0.1",port=5000)


该段代码有5个参数

  • method:方法名字
  • path:py文件路径
  • args:python方法参数
  • type:参数类型,支持map和array
  • sys:依赖库地址,在Python使用虚拟环境时可以使用
接下来使用python写个简单demoo

import requests
import json

def add(a,b):
	a = 1
	b = 2
	return a+b,a,b

def test():
	url = "https://www.baidu.com"

	response = requests.request("GET", url)
	data=json.dumps({"test":"该方法只是为了测试有依赖情况下是否可以使用"})
	return data

该py文件地址在/home/lihang/PycharmProjects/test/test.py

我们先使用postman测试一下


很明显成功了,接着使用各种编程语言尝试

Java
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n    \"method\":\"test\",\n    \"type\":\"map\",\n    \"path\":\"/home/lihang/PycharmProjects/test/test.py\",\n    \"args\":{\n    },\n    \"sys\":[]\n}");
Request request = new Request.Builder()
  .url("http://127.0.0.1:5000/")
  .method("POST", body)
  .addHeader("Content-Type", "application/json")
  .build();
Response response = client.newCall(request).execute();
Go
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "http://127.0.0.1:5000/"
  method := "POST"

  payload := strings.NewReader(`{
    "method":"test",
    "type":"map",
    "path":"/home/lihang/PycharmProjects/test/test.py",
    "args":{
    },
    "sys":[]
}`)

  client := &http.Client {
  }
  req, err := http.NewRequest(method, url, payload)

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Content-Type", "application/json")

  res, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer res.Body.Close()

  body, err := ioutil.ReadAll(res.Body)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(string(body))
}
bash
curl --location --request POST 'http://127.0.0.1:5000/' \
--header 'Content-Type: application/json' \
--data-raw '{
    "method":"test",
    "type":"map",
    "path":"/home/lihang/PycharmProjects/test/test.py",
    "args":{
    },
    "sys":[]
}'
Ruby
require "uri"
require "json"
require "net/http"

url = URI("http://127.0.0.1:5000/")

http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request.body = JSON.dump({
  "method": "test",
  "type": "map",
  "path": "/home/lihang/PycharmProjects/test/test.py",
  "args": {},
  "sys": []
})

response = http.request(request)
puts response.read_body

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/571381.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存