OllamaInterface/RunOllamaServerDialog.py

changeset 7
eb1dec15b2f0
child 8
3118d16e526e
equal deleted inserted replaced
6:d8064fb63eac 7:eb1dec15b2f0
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2020 - 2024 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to run the ollama server locally.
8 """
9
10 from PyQt6.QtCore import QProcess, Qt, QTimer, pyqtSignal, pyqtSlot
11 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
12
13 from eric7.EricWidgets import EricMessageBox
14
15 from .Ui_RunOllamaServerDialog import Ui_RunOllamaServerDialog
16
17
18 class RunOllamaServerDialog(QDialog, Ui_RunOllamaServerDialog):
19 """
20 Class implementing a dialog to run the ollama server locally.
21
22 @signal serverStarted() emitted after the start of the 'ollama' server
23 @signal serverStopped() emitted after the 'ollama' server was stopped
24 """
25
26 serverStarted = pyqtSignal()
27 serverStopped = pyqtSignal()
28
29 def __init__(self, ollamaClient, plugin, parent=None):
30 """
31 Constructor
32
33 @param ollamaClient reference to the 'ollama' client object
34 @type OllamaClient
35 @param plugin reference to the plug-in object
36 @type PluginOllamaInterface
37 @param parent reference to the parent widget
38 @type QWidget
39 """
40 super().__init__(parent)
41 self.setupUi(self)
42
43 self.__plugin = plugin
44 self.__ui = parent
45 self.__client = ollamaClient
46
47 self.__process = None
48
49 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True)
50 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
51
52 self.__defaultTextFormat = self.outputEdit.currentCharFormat()
53
54 def startServer(self):
55 """
56 Public method to start the ollama server process.
57
58 @return flag indicating success
59 @rtype bool
60 """
61 env = self.__ui.prepareServerRuntimeEnvironment()
62 self.__process = QProcess()
63 self.__process.setProcessEnvironment(env)
64 self.__process.setProcessChannelMode(QProcess.ProcessChannelMode.MergedChannels)
65
66 self.__process.readyReadStandardOutput.connect(self.__readStdOut)
67 self.__process.finished.connect(self.__processFinished)
68
69 self.outputEdit.clear()
70
71 command = "ollama"
72 args = ["serve"]
73
74 self.__process.start(command, args)
75 ok = self.__process.waitForStarted(10000)
76 if not ok:
77 EricMessageBox.critical(
78 None,
79 self.tr("Run Local ollama Server"),
80 self.tr("""The loacl ollama server process could not be started."""),
81 )
82 else:
83 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(
84 False
85 )
86 self.stopServerButton.setEnabled(True)
87 self.stopServerButton.setDefault(True)
88 self.restartServerButton.setEnabled(True)
89
90 self.serverStarted.emit()
91
92 return ok
93
94 def closeEvent(self, evt):
95 """
96 Protected method handling a close event.
97
98 @param evt reference to the close event
99 @type QCloseEvent
100 """
101 self.on_stopServerButton_clicked()
102 evt.accept()
103
104 @pyqtSlot()
105 def __readStdOut(self):
106 """
107 Private slot to add the server process output to the output pane.
108 """
109 if self.__process is not None:
110 out = str(self.__process.readAllStandardOutput(), "utf-8")
111 self.outputEdit.insertPlainText(out)
112
113 @pyqtSlot()
114 def __processFinished(self):
115 """
116 Private slot handling the finishing of the server process.
117 """
118 if (
119 self.__process is not None
120 and self.__process.state() != QProcess.ProcessState.NotRunning
121 ):
122 self.__process.terminate()
123 QTimer.singleShot(2000, self.__process.kill)
124 self.__process.waitForFinished(3000)
125
126 self.__process = None
127
128 self.restartServerButton.setEnabled(True)
129 self.stopServerButton.setEnabled(False)
130 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True)
131 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
132 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setFocus(
133 Qt.FocusReason.OtherFocusReason
134 )
135
136 self.serverStopped.emit()
137
138 @pyqtSlot()
139 def on_stopServerButton_clicked(self):
140 """
141 Private slot to stop the running server.
142 """
143 self.__process.terminate()
144
145 @pyqtSlot()
146 def on_restartServerButton_clicked(self):
147 """
148 Private slot to re-start the ollama server.
149 """
150 # step 1: stop the current server
151 if self.__process is not None:
152 self.on_stopServerButton_clicked()
153
154 # step 2: start a new server
155 self.startServer()

eric ide

mercurial