waldiez 0.1.7__py3-none-any.whl → 0.1.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of waldiez might be problematic. Click here for more details.

@@ -1,343 +0,0 @@
1
- """TCP socket input provider.
2
-
3
- It connects to a TCP server,
4
- listens for `PROVIDE:` messages to receive prompts,
5
- and sends `USE:` messages to pass the response.
6
- """
7
-
8
- import logging
9
- import socket
10
- import threading
11
- import time
12
- from types import TracebackType
13
- from typing import Optional, Type
14
-
15
- END_OF_MESSAGE = b"\r\n"
16
- LOGGER = logging.getLogger("tcp::provider")
17
-
18
-
19
- class InputProviderThread(threading.Thread):
20
- """Input provider thread."""
21
-
22
- def __init__(
23
- self,
24
- host: str,
25
- port: int,
26
- response: Optional[str],
27
- timeout: Optional[float] = None,
28
- ) -> None:
29
- """Create a new input provider thread.
30
-
31
- Parameters
32
- ----------
33
- host : str
34
- The host to connect to.
35
- port : int
36
- The port to connect to.
37
- response : str, optional
38
- The response to send.
39
- timeout : float, optional
40
- The timeout for the provider, by default None (no timeout).
41
- """
42
- super().__init__(
43
- name="InputProviderThread",
44
- daemon=True,
45
- target=self.run,
46
- )
47
- self.host = host
48
- self.port = port
49
- self.timeout = timeout
50
- self._response = response
51
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
52
- self.running = False
53
-
54
- @property
55
- def response(self) -> Optional[str]:
56
- """Get the response."""
57
- return self._response
58
-
59
- @response.setter
60
- def response(self, response: str) -> None:
61
- """Set the response.
62
-
63
- Parameters
64
- ----------
65
- response : str
66
- The response to set.
67
- """
68
- self._response = response
69
-
70
- def _run_no_timeout(self) -> None:
71
- """Start the provider."""
72
- self.socket.connect((self.host, self.port))
73
- self.socket.sendall("PROVIDER\r\n".encode("utf-8"))
74
- self.running = True
75
- while self.running:
76
- data = b""
77
- while not data.endswith(END_OF_MESSAGE):
78
- try:
79
- data += self.socket.recv(1024)
80
- except BaseException: # pylint: disable=broad-except
81
- break
82
- if not data:
83
- break
84
- if data.startswith(b"PROVIDE:"):
85
- prompt = data[len(b"PROVIDE:") : -len(END_OF_MESSAGE)]
86
- LOGGER.debug("Got a prompt: %s", prompt)
87
- if self.response:
88
- message = f"USE:{self.response}" + "\r\n"
89
- self.socket.sendall(message.encode("utf-8"))
90
- self.socket.close()
91
- self.running = False
92
-
93
- def _run_with_timeout(self, timeout: float) -> None:
94
- """Start the provider with a timeout."""
95
- self.socket.connect((self.host, self.port))
96
- self.socket.sendall("PROVIDER\r\n".encode("utf-8"))
97
- self.running = True
98
- start_time = time.monotonic()
99
- while self.running:
100
- data = b""
101
- while time.monotonic() - start_time < timeout:
102
- try:
103
- data += self.socket.recv(1024)
104
- except BaseException: # pylint: disable=broad-except
105
- break
106
- if data.endswith(END_OF_MESSAGE):
107
- break
108
- if not data:
109
- break
110
- if data.startswith(b"PROVIDE:"):
111
- prompt = data[len(b"PROVIDE:") : -len(END_OF_MESSAGE)]
112
- LOGGER.debug("Got a prompt: %s", prompt)
113
- if self.response:
114
- message = f"USE:{self.response}" + "\r\n"
115
- self.socket.sendall(message.encode("utf-8"))
116
- self.socket.close()
117
- self.running = False
118
-
119
- def run(self) -> None:
120
- """Run the provider."""
121
- if self.timeout is None or self.timeout < 1:
122
- self._run_no_timeout()
123
- else:
124
- self._run_with_timeout(self.timeout)
125
-
126
-
127
- class InputProviderWrapper:
128
- """Input provider wrapper."""
129
-
130
- thread: Optional[InputProviderThread] = None
131
-
132
- def __init__(
133
- self,
134
- host: str,
135
- port: int,
136
- response: Optional[str] = None,
137
- timeout: Optional[float] = None,
138
- ) -> None:
139
- """Create a new input provider wrapper.
140
-
141
- Parameters
142
- ----------
143
- host : str
144
- The host to connect to.
145
- port : int
146
- The port to connect to.
147
- response : str, optional
148
- The response to send.
149
- timeout : float, optional
150
- The timeout for the provider, by default None (no timeout).
151
- """
152
- self._host = host
153
- self._port = port
154
- self._timeout = timeout
155
- self._response = response
156
-
157
- @property
158
- def response(self) -> Optional[str]:
159
- """Get the response."""
160
- if self.thread:
161
- return self.thread.response
162
- return self._response
163
-
164
- def start(self) -> None:
165
- """Start the provider."""
166
- self.thread = InputProviderThread(
167
- self._host, self._port, self._response, self._timeout
168
- )
169
- self.thread.daemon = True
170
- self.thread.start()
171
-
172
- def set_response(self, response: str) -> None:
173
- """Set the response.
174
-
175
- Parameters
176
- ----------
177
- response : str
178
- The response to set.
179
- """
180
- self._response = response
181
- if self.thread:
182
- self.thread.response = response
183
-
184
- def stop(self) -> None:
185
- """Stop the provider."""
186
- if self.thread:
187
- self.thread.running = False
188
- try:
189
- self.thread.socket.close()
190
- except OSError: # pragma: no cover
191
- pass
192
- self.thread.join(timeout=0)
193
- del self.thread
194
- self.thread = None
195
-
196
-
197
- class TCPProvider:
198
- """Input provider."""
199
-
200
- _wrapper: Optional[InputProviderWrapper] = None
201
-
202
- def __init__(
203
- self,
204
- host: str,
205
- port: int,
206
- response: Optional[str] = None,
207
- timeout: Optional[float] = 30,
208
- ) -> None:
209
- """Create a new input provider.
210
-
211
- Parameters
212
- ----------
213
- host : str
214
- The host to connect to.
215
- port : int
216
- The port to connect to.
217
- response : str, optional
218
- The response to send.
219
- timeout : float, optional
220
- The timeout for the provider, by default 30.
221
- """
222
- self._host = host
223
- self._port = port
224
- self._response = response
225
- self._timeout = timeout
226
- self._start_called = False
227
- self._init_wrapper()
228
-
229
- def __enter__(self) -> "TCPProvider":
230
- """Enter the context."""
231
- self.start()
232
- return self
233
-
234
- def __exit__(
235
- self,
236
- exc_type: Optional[Type[BaseException]],
237
- exc_value: Optional[BaseException],
238
- traceback: Optional[TracebackType],
239
- ) -> None:
240
- """Exit the context."""
241
- self.stop()
242
-
243
- @property
244
- def thread(self) -> Optional[InputProviderThread]:
245
- """Get the thread."""
246
- if not self._wrapper:
247
- return None
248
- return self._wrapper.thread
249
-
250
- @property
251
- def response(self) -> Optional[str]:
252
- """Get the response."""
253
- if self._wrapper:
254
- return self._wrapper.response
255
- return self._response
256
-
257
- def _init_wrapper(self) -> None:
258
- """Initialize the wrapper."""
259
- self._wrapper = InputProviderWrapper(
260
- host=self._host,
261
- port=self._port,
262
- response=self._response,
263
- timeout=self._timeout,
264
- )
265
-
266
- def is_running(self) -> bool:
267
- """Check if the provider is running.
268
-
269
- Returns
270
- -------
271
- bool
272
- True if the provider is running, False otherwise.
273
- """
274
- if not self._wrapper:
275
- return False
276
- if not self.thread:
277
- return False
278
- return self.thread.running is True
279
-
280
- def wait(self, timeout: float) -> None:
281
- """Wait until the provider is running.
282
-
283
- Parameters
284
- ----------
285
- timeout : float
286
- The timeout to wait.
287
- """
288
- start_time = time.time()
289
- while not self.is_running():
290
- if time.time() - start_time > timeout:
291
- break
292
- time.sleep(1)
293
-
294
- def start(self) -> None:
295
- """Start the provider.
296
-
297
- Raises
298
- ------
299
- RuntimeError
300
- If the wrapper is not initialized.
301
- """
302
- # avoid starting the provider multiple times
303
- # (if the wrapped thread has not yet started)
304
- if self._start_called is True:
305
- return
306
- self._start_called = True
307
- if self.is_running():
308
- return
309
- if not self._wrapper:
310
- raise RuntimeError("Wrapper not initialized")
311
- self._wrapper.start()
312
-
313
- def set_response(self, response: str) -> None:
314
- """Set the response.
315
-
316
- Parameters
317
- ----------
318
- response : str
319
- The response to set.
320
-
321
- Raises
322
- ------
323
- RuntimeError
324
- If the wrapper is not initialized.
325
- """
326
- if not self._wrapper:
327
- raise RuntimeError("Wrapper not initialized")
328
- self._wrapper.set_response(response or "\n")
329
-
330
- def stop(self) -> None:
331
- """Stop the provider."""
332
- self._start_called = False
333
- if not self.is_running():
334
- return
335
- if self._wrapper:
336
- self._wrapper.stop()
337
- del self._wrapper
338
- self._init_wrapper()
339
-
340
- def restart(self) -> None:
341
- """Restart the provider."""
342
- self.stop()
343
- self.start()