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

Public Member Functions

 __init__ (self, enable_http=True, verify=True, enable_http2=False, max_connections=None, max_keepalive_connections=None, keepalive_expiry=None, proxies=None, using_tor_proxy=False, local_addresses=None, retries=0, retry_on_http_error=None, max_redirects=30, logger_name=None)
 
 check_parameters (self)
 
 iter_ipaddresses (self)
 
 get_ipaddress_cycle (self)
 
 iter_proxies (self)
 
 get_proxy_cycles (self)
 
 log_response (self, httpx.Response response)
 
 get_client (self, verify=None, max_redirects=None)
 
 aclose (self)
 
 is_valid_response (self, response)
 
 call_client (self, stream, method, url, **kwargs)
 
 request (self, method, url, **kwargs)
 
 stream (self, method, url, **kwargs)
 
 aclose_all (cls)
 

Static Public Member Functions

bool check_tor_proxy (httpx.AsyncClient client, proxies)
 
 extract_kwargs_clients (kwargs)
 
 extract_do_raise_for_httperror (kwargs)
 
 patch_response (response, do_raise_for_httperror)
 

Public Attributes

 enable_http = enable_http
 
 verify = verify
 
 enable_http2 = enable_http2
 
 max_connections = max_connections
 
 max_keepalive_connections = max_keepalive_connections
 
 keepalive_expiry = keepalive_expiry
 
 proxies = proxies
 
 using_tor_proxy = using_tor_proxy
 
 local_addresses = local_addresses
 
 retries = retries
 
 retry_on_http_error = retry_on_http_error
 
 max_redirects = max_redirects
 

Protected Attributes

 _local_addresses_cycle = self.get_ipaddress_cycle()
 
 _proxies_cycle = self.get_proxy_cycles()
 
dict _clients = {}
 
 _logger = logger.getChild(logger_name) if logger_name else logger
 

Static Protected Attributes

dict _TOR_CHECK_RESULT = {}
 

Static Private Attributes

tuple __slots__
 

Detailed Description

Definition at line 38 of file network.py.

Constructor & Destructor Documentation

◆ __init__()

searx.network.network.Network.__init__ ( self,
enable_http = True,
verify = True,
enable_http2 = False,
max_connections = None,
max_keepalive_connections = None,
keepalive_expiry = None,
proxies = None,
using_tor_proxy = False,
local_addresses = None,
retries = 0,
retry_on_http_error = None,
max_redirects = 30,
logger_name = None )

Definition at line 61 of file network.py.

77 ):
78
79 self.enable_http = enable_http
80 self.verify = verify
81 self.enable_http2 = enable_http2
82 self.max_connections = max_connections
83 self.max_keepalive_connections = max_keepalive_connections
84 self.keepalive_expiry = keepalive_expiry
85 self.proxies = proxies
86 self.using_tor_proxy = using_tor_proxy
87 self.local_addresses = local_addresses
88 self.retries = retries
89 self.retry_on_http_error = retry_on_http_error
90 self.max_redirects = max_redirects
91 self._local_addresses_cycle = self.get_ipaddress_cycle()
92 self._proxies_cycle = self.get_proxy_cycles()
93 self._clients = {}
94 self._logger = logger.getChild(logger_name) if logger_name else logger
95 self.check_parameters()
96

Member Function Documentation

◆ aclose()

searx.network.network.Network.aclose ( self)

Definition at line 207 of file network.py.

207 async def aclose(self):
208 async def close_client(client):
209 try:
210 await client.aclose()
211 except httpx.HTTPError:
212 pass
213
214 await asyncio.gather(*[close_client(client) for client in self._clients.values()], return_exceptions=False)
215

References searx.network.network.Network._clients.

◆ aclose_all()

searx.network.network.Network.aclose_all ( cls)

Definition at line 295 of file network.py.

295 async def aclose_all(cls):
296 await asyncio.gather(*[network.aclose() for network in NETWORKS.values()], return_exceptions=False)
297
298

◆ call_client()

searx.network.network.Network.call_client ( self,
stream,
method,
url,
** kwargs )

Definition at line 259 of file network.py.

259 async def call_client(self, stream, method, url, **kwargs):
260 retries = self.retries
261 was_disconnected = False
262 do_raise_for_httperror = Network.extract_do_raise_for_httperror(kwargs)
263 kwargs_clients = Network.extract_kwargs_clients(kwargs)
264 while retries >= 0: # pragma: no cover
265 client = await self.get_client(**kwargs_clients)
266 try:
267 if stream:
268 response = client.stream(method, url, **kwargs)
269 else:
270 response = await client.request(method, url, **kwargs)
271 if self.is_valid_response(response) or retries <= 0:
272 return Network.patch_response(response, do_raise_for_httperror)
273 except httpx.RemoteProtocolError as e:
274 if not was_disconnected:
275 # the server has closed the connection:
276 # try again without decreasing the retries variable & with a new HTTP client
277 was_disconnected = True
278 await client.aclose()
279 self._logger.warning('httpx.RemoteProtocolError: the server has disconnected, retrying')
280 continue
281 if retries <= 0:
282 raise e
283 except (httpx.RequestError, httpx.HTTPStatusError) as e:
284 if retries <= 0:
285 raise e
286 retries -= 1
287

References searx.network.network.Network._logger, searx.network.network.Network.get_client(), searx.network.network.Network.is_valid_response(), and searx.network.network.Network.retries.

Referenced by searx.network.network.Network.request(), and searx.network.network.Network.stream().

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

◆ check_parameters()

searx.network.network.Network.check_parameters ( self)

Definition at line 97 of file network.py.

97 def check_parameters(self):
98 for address in self.iter_ipaddresses():
99 if '/' in address:
100 ipaddress.ip_network(address, False)
101 else:
102 ipaddress.ip_address(address)
103
104 if self.proxies is not None and not isinstance(self.proxies, (str, dict)):
105 raise ValueError('proxies type has to be str, dict or None')
106

References searx.network.network.Network.iter_ipaddresses(), and searx.network.network.Network.proxies.

+ Here is the call graph for this function:

◆ check_tor_proxy()

bool searx.network.network.Network.check_tor_proxy ( httpx.AsyncClient client,
proxies )
static

Definition at line 160 of file network.py.

160 async def check_tor_proxy(client: httpx.AsyncClient, proxies) -> bool:
161 if proxies in Network._TOR_CHECK_RESULT:
162 return Network._TOR_CHECK_RESULT[proxies]
163
164 result = True
165 # ignore client._transport because it is not used with all://
166 for transport in client._mounts.values(): # pylint: disable=protected-access
167 if isinstance(transport, AsyncHTTPTransportNoHttp):
168 continue
169 if getattr(transport, "_pool") and getattr(
170 transport._pool, "_rdns", False # pylint: disable=protected-access
171 ):
172 continue
173 return False
174 response = await client.get("https://check.torproject.org/api/ip", timeout=60)
175 if not response.json()["IsTor"]:
176 result = False
177 Network._TOR_CHECK_RESULT[proxies] = result
178 return result
179

Referenced by searx.network.network.Network.get_client().

+ Here is the caller graph for this function:

◆ extract_do_raise_for_httperror()

searx.network.network.Network.extract_do_raise_for_httperror ( kwargs)
static

Definition at line 229 of file network.py.

229 def extract_do_raise_for_httperror(kwargs):
230 do_raise_for_httperror = True
231 if 'raise_for_httperror' in kwargs:
232 do_raise_for_httperror = kwargs['raise_for_httperror']
233 del kwargs['raise_for_httperror']
234 return do_raise_for_httperror
235

◆ extract_kwargs_clients()

searx.network.network.Network.extract_kwargs_clients ( kwargs)
static

Definition at line 217 of file network.py.

217 def extract_kwargs_clients(kwargs):
218 kwargs_clients = {}
219 if 'verify' in kwargs:
220 kwargs_clients['verify'] = kwargs.pop('verify')
221 if 'max_redirects' in kwargs:
222 kwargs_clients['max_redirects'] = kwargs.pop('max_redirects')
223 if 'allow_redirects' in kwargs:
224 # see https://github.com/encode/httpx/pull/1808
225 kwargs['follow_redirects'] = kwargs.pop('allow_redirects')
226 return kwargs_clients
227

◆ get_client()

searx.network.network.Network.get_client ( self,
verify = None,
max_redirects = None )

Definition at line 180 of file network.py.

180 async def get_client(self, verify=None, max_redirects=None):
181 verify = self.verify if verify is None else verify
182 max_redirects = self.max_redirects if max_redirects is None else max_redirects
183 local_address = next(self._local_addresses_cycle)
184 proxies = next(self._proxies_cycle) # is a tuple so it can be part of the key
185 key = (verify, max_redirects, local_address, proxies)
186 hook_log_response = self.log_response if searx_debug else None
187 if key not in self._clients or self._clients[key].is_closed:
188 client = new_client(
189 self.enable_http,
190 verify,
191 self.enable_http2,
192 self.max_connections,
193 self.max_keepalive_connections,
194 self.keepalive_expiry,
195 dict(proxies),
196 local_address,
197 0,
198 max_redirects,
199 hook_log_response,
200 )
201 if self.using_tor_proxy and not await self.check_tor_proxy(client, proxies):
202 await client.aclose()
203 raise httpx.ProxyError('Network configuration problem: not using Tor')
204 self._clients[key] = client
205 return self._clients[key]
206

References searx.network.network.Network._clients, searx.network.network.Network._local_addresses_cycle, searx.network.network.Network._proxies_cycle, searx.network.network.Network.check_tor_proxy(), searx.network.network.Network.enable_http, searx.network.network.Network.enable_http2, searx.network.network.Network.keepalive_expiry, searx.network.network.Network.log_response(), searx.network.network.Network.max_connections, searx.network.network.Network.max_keepalive_connections, searx.network.network.Network.max_redirects, searx.network.network.Network.using_tor_proxy, and searx.network.network.Network.verify.

Referenced by searx.network.network.Network.call_client().

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

◆ get_ipaddress_cycle()

searx.network.network.Network.get_ipaddress_cycle ( self)

Definition at line 115 of file network.py.

115 def get_ipaddress_cycle(self):
116 while True:
117 count = 0
118 for address in self.iter_ipaddresses():
119 if '/' in address:
120 for a in ipaddress.ip_network(address, False).hosts():
121 yield str(a)
122 count += 1
123 else:
124 a = ipaddress.ip_address(address)
125 yield str(a)
126 count += 1
127 if count == 0:
128 yield None
129

References searx.network.network.Network.iter_ipaddresses().

+ Here is the call graph for this function:

◆ get_proxy_cycles()

searx.network.network.Network.get_proxy_cycles ( self)

Definition at line 143 of file network.py.

143 def get_proxy_cycles(self):
144 proxy_settings = {}
145 for pattern, proxy_urls in self.iter_proxies():
146 proxy_settings[pattern] = cycle(proxy_urls)
147 while True:
148 # pylint: disable=stop-iteration-return
149 yield tuple((pattern, next(proxy_url_cycle)) for pattern, proxy_url_cycle in proxy_settings.items())
150

References searx.network.network.Network.iter_proxies().

+ Here is the call graph for this function:

◆ is_valid_response()

searx.network.network.Network.is_valid_response ( self,
response )

Definition at line 249 of file network.py.

249 def is_valid_response(self, response):
250 # pylint: disable=too-many-boolean-expressions
251 if (
252 (self.retry_on_http_error is True and 400 <= response.status_code <= 599)
253 or (isinstance(self.retry_on_http_error, list) and response.status_code in self.retry_on_http_error)
254 or (isinstance(self.retry_on_http_error, int) and response.status_code == self.retry_on_http_error)
255 ):
256 return False
257 return True
258

References searx.network.network.Network.retry_on_http_error.

Referenced by searx.network.network.Network.call_client().

+ Here is the caller graph for this function:

◆ iter_ipaddresses()

searx.network.network.Network.iter_ipaddresses ( self)

Definition at line 107 of file network.py.

107 def iter_ipaddresses(self):
108 local_addresses = self.local_addresses
109 if not local_addresses:
110 return
111 if isinstance(local_addresses, str):
112 local_addresses = [local_addresses]
113 yield from local_addresses
114

References searx.network.network.Network.local_addresses.

Referenced by searx.network.network.Network.check_parameters(), and searx.network.network.Network.get_ipaddress_cycle().

+ Here is the caller graph for this function:

◆ iter_proxies()

searx.network.network.Network.iter_proxies ( self)

Definition at line 130 of file network.py.

130 def iter_proxies(self):
131 if not self.proxies:
132 return
133 # https://www.python-httpx.org/compatibility/#proxy-keys
134 if isinstance(self.proxies, str):
135 yield 'all://', [self.proxies]
136 else:
137 for pattern, proxy_url in self.proxies.items():
138 pattern = PROXY_PATTERN_MAPPING.get(pattern, pattern)
139 if isinstance(proxy_url, str):
140 proxy_url = [proxy_url]
141 yield pattern, proxy_url
142

References searx.network.network.Network.proxies.

Referenced by searx.network.network.Network.get_proxy_cycles().

+ Here is the caller graph for this function:

◆ log_response()

searx.network.network.Network.log_response ( self,
httpx.Response response )

Definition at line 151 of file network.py.

151 async def log_response(self, response: httpx.Response):
152 request = response.request
153 status = f"{response.status_code} {response.reason_phrase}"
154 response_line = f"{response.http_version} {status}"
155 content_type = response.headers.get("Content-Type")
156 content_type = f' ({content_type})' if content_type else ''
157 self._logger.debug(f'HTTP Request: {request.method} {request.url} "{response_line}"{content_type}')
158

References searx.network.network.Network._logger.

Referenced by searx.network.network.Network.get_client().

+ Here is the caller graph for this function:

◆ patch_response()

searx.network.network.Network.patch_response ( response,
do_raise_for_httperror )
static

Definition at line 237 of file network.py.

237 def patch_response(response, do_raise_for_httperror):
238 if isinstance(response, httpx.Response):
239 # requests compatibility (response is not streamed)
240 # see also https://www.python-httpx.org/compatibility/#checking-for-4xx5xx-responses
241 response.ok = not response.is_error
242
243 # raise an exception
244 if do_raise_for_httperror:
245 raise_for_httperror(response)
246
247 return response
248

◆ request()

searx.network.network.Network.request ( self,
method,
url,
** kwargs )

Definition at line 288 of file network.py.

288 async def request(self, method, url, **kwargs):
289 return await self.call_client(False, method, url, **kwargs)
290

References searx.network.network.Network.call_client().

+ Here is the call graph for this function:

◆ stream()

searx.network.network.Network.stream ( self,
method,
url,
** kwargs )

Definition at line 291 of file network.py.

291 async def stream(self, method, url, **kwargs):
292 return await self.call_client(True, method, url, **kwargs)
293

References searx.network.network.Network.call_client().

Referenced by searx.webutils.CSVWriter.writerow().

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

Member Data Documentation

◆ __slots__

tuple searx.network.network.Network.__slots__
staticprivate
Initial value:
= (
'enable_http',
'verify',
'enable_http2',
'max_connections',
'max_keepalive_connections',
'keepalive_expiry',
'local_addresses',
'proxies',
'using_tor_proxy',
'max_redirects',
'retries',
'retry_on_http_error',
'_local_addresses_cycle',
'_proxies_cycle',
'_clients',
'_logger',
)

Definition at line 40 of file network.py.

◆ _clients

dict searx.network.network.Network._clients = {}
protected

◆ _local_addresses_cycle

searx.network.network.Network._local_addresses_cycle = self.get_ipaddress_cycle()
protected

Definition at line 91 of file network.py.

Referenced by searx.network.network.Network.get_client().

◆ _logger

searx.network.network.Network._logger = logger.getChild(logger_name) if logger_name else logger
protected

◆ _proxies_cycle

searx.network.network.Network._proxies_cycle = self.get_proxy_cycles()
protected

Definition at line 92 of file network.py.

Referenced by searx.network.network.Network.get_client().

◆ _TOR_CHECK_RESULT

dict searx.network.network.Network._TOR_CHECK_RESULT = {}
staticprotected

Definition at line 59 of file network.py.

◆ enable_http

searx.network.network.Network.enable_http = enable_http

Definition at line 79 of file network.py.

Referenced by searx.network.network.Network.get_client().

◆ enable_http2

searx.network.network.Network.enable_http2 = enable_http2

Definition at line 81 of file network.py.

Referenced by searx.network.network.Network.get_client().

◆ keepalive_expiry

searx.network.network.Network.keepalive_expiry = keepalive_expiry

Definition at line 84 of file network.py.

Referenced by searx.network.network.Network.get_client().

◆ local_addresses

searx.network.network.Network.local_addresses = local_addresses

Definition at line 87 of file network.py.

Referenced by searx.network.network.Network.iter_ipaddresses().

◆ max_connections

searx.network.network.Network.max_connections = max_connections

Definition at line 82 of file network.py.

Referenced by searx.network.network.Network.get_client().

◆ max_keepalive_connections

searx.network.network.Network.max_keepalive_connections = max_keepalive_connections

Definition at line 83 of file network.py.

Referenced by searx.network.network.Network.get_client().

◆ max_redirects

searx.network.network.Network.max_redirects = max_redirects

Definition at line 90 of file network.py.

Referenced by searx.network.network.Network.get_client().

◆ proxies

searx.network.network.Network.proxies = proxies

◆ retries

searx.network.network.Network.retries = retries

Definition at line 88 of file network.py.

Referenced by searx.network.network.Network.call_client().

◆ retry_on_http_error

searx.network.network.Network.retry_on_http_error = retry_on_http_error

Definition at line 89 of file network.py.

Referenced by searx.network.network.Network.is_valid_response().

◆ using_tor_proxy

searx.network.network.Network.using_tor_proxy = using_tor_proxy

Definition at line 86 of file network.py.

Referenced by searx.network.network.Network.get_client().

◆ verify

searx.network.network.Network.verify = verify

Definition at line 80 of file network.py.

Referenced by searx.network.network.Network.get_client().


The documentation for this class was generated from the following file: