From a1a38d5ad206a5a9ff8459d8cf360cff6425dcbe Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 14 Jan 2024 05:57:33 +0900 Subject: [PATCH] Add Python server setup and dependencies installation --- src-tauri/key.txt | 1 + src-tauri/src-python/main.py | 5 ++++ src-tauri/src-python/requirements.txt | 4 +++ src-tauri/src-python/run.py | 4 --- src-tauri/src/main.rs | 41 ++++++++++++++++++++++++++- src/ts/process/models/local.ts | 29 +++++++++++++++---- 6 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 src-tauri/key.txt create mode 100644 src-tauri/src-python/requirements.txt diff --git a/src-tauri/key.txt b/src-tauri/key.txt new file mode 100644 index 00000000..8a24b62a --- /dev/null +++ b/src-tauri/key.txt @@ -0,0 +1 @@ +6a8c5a113f37455a800a5ac250d241a0 \ No newline at end of file diff --git a/src-tauri/src-python/main.py b/src-tauri/src-python/main.py index 50ce1897..3e08d7f9 100644 --- a/src-tauri/src-python/main.py +++ b/src-tauri/src-python/main.py @@ -2,10 +2,15 @@ from fastapi import FastAPI, Header from fastapi.responses import StreamingResponse from llamacpp import LlamaItem, stream_chat_llamacpp from typing import Annotated, Union +import uuid import os app = FastAPI() key_dir = os.path.join(os.getcwd(), "key.txt") +if not os.path.exists(key_dir): + f = open(key_dir, 'w') + f.write(str(uuid.uuid4())) + f.close() f = open(key_dir, 'r') key = f.read() f.close() diff --git a/src-tauri/src-python/requirements.txt b/src-tauri/src-python/requirements.txt new file mode 100644 index 00000000..1094c980 --- /dev/null +++ b/src-tauri/src-python/requirements.txt @@ -0,0 +1,4 @@ +pydantic +llama-cpp-python +uvicorn[standard] +fastapi \ No newline at end of file diff --git a/src-tauri/src-python/run.py b/src-tauri/src-python/run.py index 2c1e49ea..6b87d72f 100644 --- a/src-tauri/src-python/run.py +++ b/src-tauri/src-python/run.py @@ -1,13 +1,9 @@ import uvicorn import os import uuid -import subprocess -import sys if __name__ == "__main__": key_dir = os.path.join(os.getcwd(), "key.txt") with open(key_dir, "w") as f: f.write(uuid.uuid4().hex) - subprocess.check_call([sys.executable, "-m", "pip", "install", "pydantic"]) - subprocess.check_call([sys.executable, "-m", "pip", "install", "llama-cpp-python"]) uvicorn.run("main:app", host="0.0.0.0", port=8912) \ No newline at end of file diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index a8306d54..e85bf625 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -279,6 +279,43 @@ fn post_py_install(path:String){ std::fs::write(&completed_path, "python311").unwrap(); } + +#[tauri::command] +fn install_py_dependencies(path:String, dependency:String) -> Result<(), String>{ + println!("installing {}", dependency); + let py_path = Path::new(&path).join("python"); + let py_exec_path = py_path.join("python.exe"); + let mut py = Command::new(py_exec_path); + let output = py.arg("-m").arg("pip").arg("install").arg(dependency).output(); + match output { + Ok(o) => { + let res = String::from_utf8(o.stdout).unwrap(); + println!("{}", res); + return Ok(()) + }, + Err(e) => { + println!("{}", e); + return Err(e.to_string()) + } + } +} + +#[tauri::command] +fn run_py_server(handle: tauri::AppHandle, py_path:String){ + let py_exec_path = Path::new(&py_path).join("python").join("python.exe"); + let server_path = handle.path_resolver().resolve_resource("src-python/run.py").expect("failed to resolve resource"); + + let mut py_server = Command::new(&py_exec_path); + //set working directory to server path + py_server.current_dir(server_path.parent().unwrap()); + + println!("server_path: {}", server_path.display()); + println!("py_exec_path: {}", py_exec_path.display()); + let mut _child = py_server.arg("-m").arg("uvicorn").arg("--port").arg("10026").arg("main:app").spawn().expect("failed to execute process"); + println!("server started"); + return +} + #[tauri::command] fn run_server_local(){ let app_base_path = tauri::api::path::data_dir().unwrap().join("co.aiclient.risu"); @@ -347,7 +384,9 @@ fn main() { run_server_local, install_python, install_pip, - post_py_install + post_py_install, + run_py_server, + install_py_dependencies ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src/ts/process/models/local.ts b/src/ts/process/models/local.ts index 1396f21e..3b7e3d88 100644 --- a/src/ts/process/models/local.ts +++ b/src/ts/process/models/local.ts @@ -159,7 +159,29 @@ export async function installPython(){ const appDir = await path.appDataDir() const completedPath = await path.join(appDir, 'python', 'completed.txt') if(await exists(completedPath)){ - alertMd("Python is already installed") + const dependencies = [ + 'pydantic', + 'scikit-build', + 'scikit-build-core', + 'pyproject_metadata', + 'pathspec', + 'llama-cpp-python', + 'uvicorn[standard]', + 'fastapi' + ] + for(const dep of dependencies){ + alertWait("Installing Python Dependencies (" + dep + ")") + await invoke('install_py_dependencies', { + path: appDir, + dependency: dep + }) + } + + const srvPath = await resolveResource('/src-python/') + await invoke('run_py_server', { + pyPath: appDir, + }) + alertMd("Python Server is running at: " + srvPath) return } @@ -175,11 +197,6 @@ export async function installPython(){ await invoke('post_py_install', { path: appDir }) - const srvPath = await resolveResource('/src-python/') - await invoke('run_py_server', { - path: srvPath - - }) alertClear() } \ No newline at end of file