sjyango commented on code in PR #57329:
URL: https://github.com/apache/doris/pull/57329#discussion_r2471609864


##########
be/src/udf/python/python_env.h:
##########
@@ -0,0 +1,187 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include <filesystem>
+
+#include "common/status.h"
+
+namespace doris {
+
+namespace fs = std::filesystem;
+
+enum class PythonEnvType { CONDA, VENV };
+
+struct PythonVersion {
+    std::string version;         // e.g. "3.9"
+    std::string full_version;    // e.g. "3.9.16"
+    std::string base_path;       // e.g. "/root/anaconda3/envs/python3.9"
+    std::string executable_path; // e.g. "{base_path}/bin/python3"
+
+    PythonVersion() = default;
+
+    PythonVersion(std::string version, std::string base_path)
+            : version(std::move(version)), base_path(std::move(base_path)) {}
+
+    explicit PythonVersion(std::string version, std::string full_version, 
std::string base_path)
+            : version(std::move(version)),
+              full_version(std::move(full_version)),
+              base_path(std::move(base_path)) {}
+
+    explicit PythonVersion(std::string version, std::string full_version, 
std::string base_path,
+                           std::string executable_path)
+            : version(std::move(version)),
+              full_version(std::move(full_version)),
+              base_path(std::move(base_path)),
+              executable_path(std::move(executable_path)) {}
+
+    bool operator==(const PythonVersion& other) const {
+        return version == other.version && full_version == other.full_version;
+    }
+
+    const std::string& get_version() const { return version; }
+    const std::string& get_base_path() const { return base_path; }
+    std::string get_executable_path() const {
+        return executable_path.empty() ? fmt::format("{}/bin/python3", 
base_path) : executable_path;
+    }
+    bool is_valid() const {
+        return !version.empty() && !base_path.empty() && fs::exists(base_path);
+    }
+    bool executable_exists() const { return fs::exists(get_executable_path()); 
}
+    std::string to_string() const {
+        return fmt::format("[version: {}, full_version: {}, base_path: {}, 
executable_path: {}]",
+                           version, full_version, base_path, executable_path);
+    }
+};
+
+struct PythonEnvironment {
+    std::string env_name;                   // e.g. "base" or "myenv"
+    std::string env_base_path;              // e.g. 
"/opt/miniconda3/envs/myenv"
+    std::string python_base_path;           // e.g. 
"/{env_base_path}/bin/python"
+    std::string python_full_version;        // e.g. "3.9.16"
+    std::string python_major_minor_version; // e.g. "3.9"
+    std::string python_dependency_path;     // e.g. 
"/{env_base_path}/lib/python3.9/site-packages"
+
+    explicit PythonEnvironment(std::string name, std::string path, std::string 
python_path,
+                               std::string full_version, std::string 
major_minor_version,
+                               std::string dependency_path);
+
+    PythonVersion to_python_version() const;
+
+    std::string to_string() const;
+
+    bool is_valid() const;
+
+    static Status scan_from_conda_root_path(const fs::path& conda_root_path,
+                                            std::vector<PythonEnvironment>* 
environments);
+
+    static Status scan_from_venv_root_path(const fs::path& venv_root_path,
+                                           const std::vector<std::string>& 
interpreter_paths,
+                                           std::vector<PythonEnvironment>* 
environments);
+};
+
+class PythonEnvScanner {
+public:
+    PythonEnvScanner(const fs::path& env_root_path) : 
env_root_path_(env_root_path) {}
+
+    virtual ~PythonEnvScanner() = default;
+
+    virtual Status scan() = 0;
+
+    Status get_versions(std::vector<PythonVersion>* versions) const;
+
+    Status get_version(const std::string& runtime_version, PythonVersion* 
version) const;
+
+    Status default_version(PythonVersion* version) const;
+
+    std::string root_path() const { return env_root_path_.string(); }
+
+    virtual PythonEnvType env_type() const = 0;
+
+    virtual std::string to_string() const = 0;
+
+protected:
+    fs::path env_root_path_;
+    std::vector<PythonEnvironment> envs_;
+};
+
+class CondaEnvScanner : public PythonEnvScanner {
+public:
+    CondaEnvScanner(const fs::path& python_root_path) : 
PythonEnvScanner(python_root_path) {}
+
+    ~CondaEnvScanner() override = default;
+
+    Status scan() override;
+
+    std::string to_string() const override;
+
+    PythonEnvType env_type() const override { return PythonEnvType::CONDA; }
+};
+
+class VenvEnvScanner : public PythonEnvScanner {
+public:
+    VenvEnvScanner(const fs::path& python_root_path,
+                   const std::vector<std::string>& interpreter_paths)
+            : PythonEnvScanner(python_root_path), 
interpreter_paths_(interpreter_paths) {}
+
+    ~VenvEnvScanner() override = default;
+
+    Status scan() override;
+
+    std::string to_string() const override;
+
+    PythonEnvType env_type() const override { return PythonEnvType::VENV; }
+
+private:
+    std::vector<std::string> interpreter_paths_;
+};
+
+class PythonVersionManager {
+public:
+    static PythonVersionManager& instance() {
+        static PythonVersionManager instance;
+        return instance;
+    }
+
+    Status init(PythonEnvType env_type, const fs::path& python_root_path,
+                const std::string& python_venv_interpreter_paths);
+
+    Status get_version(const std::string& runtime_version, PythonVersion* 
version) const {
+        return env_scanner_->get_version(runtime_version, version);
+    }
+
+    Status default_version(PythonVersion* version) const {
+        return env_scanner_->default_version(version);
+    }
+
+    std::string to_string() const { return env_scanner_->to_string(); }
+
+private:
+    std::shared_ptr<PythonEnvScanner> env_scanner_;

Review Comment:
   Using unique_ptr is better. I will fix it



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to