.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.network Namespace Reference

Namespaces

namespace  client
 
namespace  network
 
namespace  raise_for_httperror
 

Classes

class  Request
 

Functions

 reset_time_for_thread ()
 
 get_time_for_thread ()
 
 set_timeout_for_thread (timeout, start_time=None)
 
 set_context_network_name (network_name)
 
 get_context_network ()
 
 _record_http_time ()
 
 _get_timeout (start_time, kwargs)
 
SXNG_Response request (method, url, **kwargs)
 
List[Union[httpx.Response, Exception]] multi_requests (List["Request"] request_list)
 
SXNG_Response get (url, **kwargs)
 
SXNG_Response options (url, **kwargs)
 
SXNG_Response head (url, **kwargs)
 
SXNG_Response post (url, data=None, **kwargs)
 
SXNG_Response put (url, data=None, **kwargs)
 
SXNG_Response patch (url, data=None, **kwargs)
 
SXNG_Response delete (url, **kwargs)
 
 stream_chunk_to_queue (network, queue, method, url, **kwargs)
 
 _stream_generator (method, url, **kwargs)
 
 _close_response_method (self)
 
Tuple[httpx.Response, Iterable[bytes]] stream (method, url, **kwargs)
 

Variables

 THREADLOCAL = threading.local()
 
# pylint disable _generator = protected-access
 

Function Documentation

◆ _close_response_method()

searx.network._close_response_method ( self)
protected

Definition at line 235 of file __init__.py.

235def _close_response_method(self):
236 asyncio.run_coroutine_threadsafe(self.aclose(), get_loop())
237 # reach the end of _self.generator ( _stream_generator ) to an avoid memory leak.
238 # it makes sure that :
239 # * the httpx response is closed (see the stream_chunk_to_queue function)
240 # * to call future.result() in _stream_generator
241 for _ in self._generator: # pylint: disable=protected-access
242 continue
243
244

◆ _get_timeout()

searx.network._get_timeout ( start_time,
kwargs )
protected

Definition at line 67 of file __init__.py.

67def _get_timeout(start_time, kwargs):
68 # pylint: disable=too-many-branches
69
70 # timeout (httpx)
71 if 'timeout' in kwargs:
72 timeout = kwargs['timeout']
73 else:
74 timeout = getattr(THREADLOCAL, 'timeout', None)
75 if timeout is not None:
76 kwargs['timeout'] = timeout
77
78 # 2 minutes timeout for the requests without timeout
79 timeout = timeout or 120
80
81 # adjust actual timeout
82 timeout += 0.2 # overhead
83 if start_time:
84 timeout -= default_timer() - start_time
85
86 return timeout
87
88

Referenced by multi_requests(), and request().

+ Here is the caller graph for this function:

◆ _record_http_time()

searx.network._record_http_time ( )
protected

Definition at line 53 of file __init__.py.

53def _record_http_time():
54 # pylint: disable=too-many-branches
55 time_before_request = default_timer()
56 start_time = getattr(THREADLOCAL, 'start_time', time_before_request)
57 try:
58 yield start_time
59 finally:
60 # update total_time.
61 # See get_time_for_thread() and reset_time_for_thread()
62 if hasattr(THREADLOCAL, 'total_time'):
63 time_after_request = default_timer()
64 THREADLOCAL.total_time += time_after_request - time_before_request
65
66

Referenced by multi_requests(), and request().

+ Here is the caller graph for this function:

◆ _stream_generator()

searx.network._stream_generator ( method,
url,
** kwargs )
protected

Definition at line 220 of file __init__.py.

220def _stream_generator(method, url, **kwargs):
221 queue = SimpleQueue()
222 network = get_context_network()
223 future = asyncio.run_coroutine_threadsafe(stream_chunk_to_queue(network, queue, method, url, **kwargs), get_loop())
224
225 # yield chunks
226 obj_or_exception = queue.get()
227 while obj_or_exception is not None:
228 if isinstance(obj_or_exception, Exception):
229 raise obj_or_exception
230 yield obj_or_exception
231 obj_or_exception = queue.get()
232 future.result()
233
234

References get_context_network(), and stream_chunk_to_queue().

Referenced by stream().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ delete()

SXNG_Response searx.network.delete ( url,
** kwargs )

Definition at line 190 of file __init__.py.

190def delete(url, **kwargs) -> SXNG_Response:
191 return request('delete', url, **kwargs)
192
193

References request().

+ Here is the call graph for this function:

◆ get()

SXNG_Response searx.network.get ( url,
** kwargs )

Definition at line 163 of file __init__.py.

163def get(url, **kwargs) -> SXNG_Response:
164 kwargs.setdefault('allow_redirects', True)
165 return request('get', url, **kwargs)
166
167

References request().

+ Here is the call graph for this function:

◆ get_context_network()

searx.network.get_context_network ( )
If set return thread's network.

If unset, return value from :py:obj:`get_network`.

Definition at line 44 of file __init__.py.

44def get_context_network():
45 """If set return thread's network.
46
47 If unset, return value from :py:obj:`get_network`.
48 """
49 return THREADLOCAL.__dict__.get('network') or get_network()
50
51
52@contextmanager

Referenced by _stream_generator(), multi_requests(), and request().

+ Here is the caller graph for this function:

◆ get_time_for_thread()

searx.network.get_time_for_thread ( )
returns thread's total time or None

Definition at line 30 of file __init__.py.

30def get_time_for_thread():
31 """returns thread's total time or None"""
32 return THREADLOCAL.__dict__.get('total_time')
33
34

◆ head()

SXNG_Response searx.network.head ( url,
** kwargs )

Definition at line 173 of file __init__.py.

173def head(url, **kwargs) -> SXNG_Response:
174 kwargs.setdefault('allow_redirects', False)
175 return request('head', url, **kwargs)
176
177

References request().

+ Here is the call graph for this function:

◆ multi_requests()

List[Union[httpx.Response, Exception]] searx.network.multi_requests ( List["Request"] request_list)
send multiple HTTP requests in parallel. Wait for all requests to finish.

Definition at line 101 of file __init__.py.

101def multi_requests(request_list: List["Request"]) -> List[Union[httpx.Response, Exception]]:
102 """send multiple HTTP requests in parallel. Wait for all requests to finish."""
103 with _record_http_time() as start_time:
104 # send the requests
105 network = get_context_network()
106 loop = get_loop()
107 future_list = []
108 for request_desc in request_list:
109 timeout = _get_timeout(start_time, request_desc.kwargs)
110 future = asyncio.run_coroutine_threadsafe(
111 network.request(request_desc.method, request_desc.url, **request_desc.kwargs), loop
112 )
113 future_list.append((future, timeout))
114
115 # read the responses
116 responses = []
117 for future, timeout in future_list:
118 try:
119 responses.append(future.result(timeout))
120 except concurrent.futures.TimeoutError:
121 responses.append(httpx.TimeoutException('Timeout', request=None))
122 except Exception as e: # pylint: disable=broad-except
123 responses.append(e)
124 return responses
125
126

References _get_timeout(), _record_http_time(), and get_context_network().

+ Here is the call graph for this function:

◆ options()

SXNG_Response searx.network.options ( url,
** kwargs )

Definition at line 168 of file __init__.py.

168def options(url, **kwargs) -> SXNG_Response:
169 kwargs.setdefault('allow_redirects', True)
170 return request('options', url, **kwargs)
171
172

References request().

+ Here is the call graph for this function:

◆ patch()

SXNG_Response searx.network.patch ( url,
data = None,
** kwargs )

Definition at line 186 of file __init__.py.

186def patch(url, data=None, **kwargs) -> SXNG_Response:
187 return request('patch', url, data=data, **kwargs)
188
189

References request().

+ Here is the call graph for this function:

◆ post()

SXNG_Response searx.network.post ( url,
data = None,
** kwargs )

Definition at line 178 of file __init__.py.

178def post(url, data=None, **kwargs) -> SXNG_Response:
179 return request('post', url, data=data, **kwargs)
180
181

References request().

+ Here is the call graph for this function:

◆ put()

SXNG_Response searx.network.put ( url,
data = None,
** kwargs )

Definition at line 182 of file __init__.py.

182def put(url, data=None, **kwargs) -> SXNG_Response:
183 return request('put', url, data=data, **kwargs)
184
185

References request().

+ Here is the call graph for this function:

◆ request()

SXNG_Response searx.network.request ( method,
url,
** kwargs )
same as requests/requests/api.py request(...)

Definition at line 89 of file __init__.py.

89def request(method, url, **kwargs) -> SXNG_Response:
90 """same as requests/requests/api.py request(...)"""
91 with _record_http_time() as start_time:
92 network = get_context_network()
93 timeout = _get_timeout(start_time, kwargs)
94 future = asyncio.run_coroutine_threadsafe(network.request(method, url, **kwargs), get_loop())
95 try:
96 return future.result(timeout)
97 except concurrent.futures.TimeoutError as e:
98 raise httpx.TimeoutException('Timeout', request=None) from e
99
100

References _get_timeout(), _record_http_time(), and get_context_network().

Referenced by delete(), get(), head(), options(), patch(), post(), and put().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reset_time_for_thread()

searx.network.reset_time_for_thread ( )

Definition at line 26 of file __init__.py.

26def reset_time_for_thread():
27 THREADLOCAL.total_time = 0
28
29

Referenced by searx.search.processors.online.OnlineProcessor.initialize(), and searx.search.processors.online.OnlineProcessor.search().

+ Here is the caller graph for this function:

◆ set_context_network_name()

searx.network.set_context_network_name ( network_name)

Definition at line 40 of file __init__.py.

40def set_context_network_name(network_name):
41 THREADLOCAL.network = get_network(network_name)
42
43

Referenced by searx.search.processors.online.OnlineProcessor.search().

+ Here is the caller graph for this function:

◆ set_timeout_for_thread()

searx.network.set_timeout_for_thread ( timeout,
start_time = None )

Definition at line 35 of file __init__.py.

35def set_timeout_for_thread(timeout, start_time=None):
36 THREADLOCAL.timeout = timeout
37 THREADLOCAL.start_time = start_time
38
39

Referenced by searx.search.processors.online.OnlineProcessor.initialize(), and searx.search.processors.online.OnlineProcessor.search().

+ Here is the caller graph for this function:

◆ stream()

Tuple[httpx.Response, Iterable[bytes]] searx.network.stream ( method,
url,
** kwargs )
Replace httpx.stream.

Usage:
response, stream = poolrequests.stream(...)
for chunk in stream:
    ...

httpx.Client.stream requires to write the httpx.HTTPTransport version of the
the httpx.AsyncHTTPTransport declared above.

Definition at line 245 of file __init__.py.

245def stream(method, url, **kwargs) -> Tuple[httpx.Response, Iterable[bytes]]:
246 """Replace httpx.stream.
247
248 Usage:
249 response, stream = poolrequests.stream(...)
250 for chunk in stream:
251 ...
252
253 httpx.Client.stream requires to write the httpx.HTTPTransport version of the
254 the httpx.AsyncHTTPTransport declared above.
255 """
256 generator = _stream_generator(method, url, **kwargs)
257
258 # yield response
259 response = next(generator) # pylint: disable=stop-iteration-return
260 if isinstance(response, Exception):
261 raise response
262
263 response._generator = generator # pylint: disable=protected-access
264 response.close = MethodType(_close_response_method, response)
265
266 return response, generator

References _stream_generator().

+ Here is the call graph for this function:

◆ stream_chunk_to_queue()

searx.network.stream_chunk_to_queue ( network,
queue,
method,
url,
** kwargs )

Definition at line 194 of file __init__.py.

194async def stream_chunk_to_queue(network, queue, method, url, **kwargs):
195 try:
196 async with await network.stream(method, url, **kwargs) as response:
197 queue.put(response)
198 # aiter_raw: access the raw bytes on the response without applying any HTTP content decoding
199 # https://www.python-httpx.org/quickstart/#streaming-responses
200 async for chunk in response.aiter_raw(65536):
201 if len(chunk) > 0:
202 queue.put(chunk)
203 except (httpx.StreamClosed, anyio.ClosedResourceError):
204 # the response was queued before the exception.
205 # the exception was raised on aiter_raw.
206 # we do nothing here: in the finally block, None will be queued
207 # so stream(method, url, **kwargs) generator can stop
208 pass
209 except Exception as e: # pylint: disable=broad-except
210 # broad except to avoid this scenario:
211 # exception in network.stream(method, url, **kwargs)
212 # -> the exception is not catch here
213 # -> queue None (in finally)
214 # -> the function below steam(method, url, **kwargs) has nothing to return
215 queue.put(e)
216 finally:
217 queue.put(None)
218
219

Referenced by _stream_generator().

+ Here is the caller graph for this function:

Variable Documentation

◆ _generator

# pylint disable searx.network._generator = protected-access
protected

Definition at line 241 of file __init__.py.

◆ THREADLOCAL

searx.network.THREADLOCAL = threading.local()

Definition at line 22 of file __init__.py.