为什么从Java运行python文件时不能导入`dotenv-python`模块?

x7yiwoj4  于 2024-01-05  发布在  Java
关注(0)|答案(1)|浏览(218)

这个脚本包含在我的Sping Boot 应用程序中。当我发送运行这个脚本的请求时,它就会自动运行。我使用py4j库来建立Java和Python之间的连接。我使用这个方法从Java运行Python文件。

  1. public void runScript(String file){
  2. try {
  3. String pythonScriptPath = "./src/main/java/com/api/air_quality/python/" + file + ".py";
  4. String pythonExecutablePath = "C:\\Users\\KAVI\\AppData\\Local\\Programs\\Python\\Python310\\python.exe";
  5. String command = pythonExecutablePath + " " + pythonScriptPath;
  6. // Append the cached data to the command
  7. for (Double value : airQualityDataCache.get()) {
  8. command += " " + value;
  9. }
  10. Process process = Runtime.getRuntime().exec(command);
  11. // output
  12. BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
  13. String line;
  14. while ((line = reader.readLine()) != null) {
  15. System.out.println(line);
  16. }
  17. // error
  18. BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  19. while ((line = errorReader.readLine()) != null) {
  20. System.err.println(line);
  21. }
  22. int exitCode = process.waitFor();
  23. if (exitCode != 0) {
  24. System.out.println("Python script exited with code: " + exitCode);
  25. }
  26. } catch (IOException | InterruptedException e) {
  27. e.printStackTrace();
  28. }
  29. }

字符串
这是我想添加.env变量的python文件。

  1. from time import sleep
  2. from dotenv import load_dotenv
  3. from py4j.java_gateway import JavaGateway
  4. import numpy as np
  5. import pickle
  6. import sys
  7. import requests
  8. import os
  9. # to ignore warnings
  10. import warnings
  11. warnings.filterwarnings('ignore')
  12. class AirHumidityModelPython:
  13. def __init__(self):
  14. self.gateway = JavaGateway()
  15. self.java_model = self.gateway.entry_point
  16. with open("./AI_Models/airHumidity_model.pkl", 'rb') as f:
  17. self.model = pickle.load(f)
  18. def predict_air_humidity(self, features):
  19. try:
  20. features_2d = np.array(features).reshape(1, -1)
  21. prediction = self.model.predict(features_2d)[0]
  22. url = os.getenv("SPRINGBOOT_URL_PYTHON")
  23. spring_boot_url = url+"/airHumidity"
  24. # Send the prediction to the Spring Boot endpoint
  25. response = requests.post(spring_boot_url, json=float(prediction))
  26. # print(response.text)
  27. return prediction
  28. except Exception as e:
  29. # Handle any errors during prediction
  30. return str(e)
  31. if __name__ == "__main__":
  32. load_dotenv()
  33. # instance
  34. air_humidity_model = AirHumidityModelPython()
  35. # dummy_features = [[1.5, 2.3, 4.2, 5.1, 7.7, 9.4, 10.0]]
  36. data_from_java = [float(arg) for arg in sys.argv[1:]]
  37. result = air_humidity_model.predict_air_humidity(data_from_java)
  38. # result = air_humidity_model.java_model.Message()


在这种情况下,工作流程是,用户将值数组发送到springboot后端,然后springboot服务运行上面的第一个方法。它将运行Python文件。然后它进行预测,并将预测值再次发送到springboot后端。Spring Boot缓存Python请求的值,并将其作为响应发送给用户。
问题是python-dotenv在运行文件时出现此错误

  1. import dotenv
  2. ModuleNotFoundError: No module named 'dotenv'


我使用以下命令将正确的python-dotenv库安装到了我的项目中。

  1. pip3 install python-dotenv


也尝试过,

  1. pip3.10 install python-dotenv


这个也是。

  1. pip3 uninstall -U python-dotenv


然后,我直接运行Python文件,而不涉及Java,它工作得很好。
只有当Python文件通过Java方法运行时才会出现错误。其他Python导入不会出现任何错误。

vzgqcmou

vzgqcmou1#

发生此错误是因为我从设备驱动器加载了python.exe,并从根venv加载了lib文件夹。当我试图从Java执行Python文件时,它无法加载一些需要激活的库。原因是执行程序和库位于不同的位置。因此,我修改了代码中的一些内容。在Python文件中,

  1. venv_path = "../../../../../../../venv"
  2. sys.path.append(venv_path + '/Lib/site-packages')

字符串
我附加了环境venv文件夹路径作为系统路径。现在这个文件路径就像它来自系统一样工作。
在Java方法中,

  1. String venvPath = "./venv";
  2. String pythonExecutablePath = venvPath + "/Scripts/python.exe";
  3. String pythonScriptPath = "./src/main/java/com/api/air_quality/python/" + file + ".py";
  4. String command = pythonExecutablePath + " " + pythonScriptPath;


我把python的可执行路径也改成了从venv根文件夹获取。现在这段代码运行良好,在部署中也不会有任何问题。

展开查看全部

相关问题