From f2a1f1362b3f2d5defb1b4a3312f38969d467d4b Mon Sep 17 00:00:00 2001 From: mdevolde Date: Sat, 22 Nov 2025 19:16:47 +0100 Subject: [PATCH] feat: added possibility to use proxies in LanguageTool requests, updated uv.lock --- language_tool_python/server.py | 43 ++++++++++++++++++++ uv.lock | 72 ---------------------------------- 2 files changed, 43 insertions(+), 72 deletions(-) diff --git a/language_tool_python/server.py b/language_tool_python/server.py index 2c57ff3..bffe83d 100644 --- a/language_tool_python/server.py +++ b/language_tool_python/server.py @@ -79,6 +79,8 @@ class LanguageTool: :type config: Optional[str] :param language_tool_download_version: The version of LanguageTool to download if needed. :type language_tool_download_version: Optional[str] + :param proxies: A dictionary of proxies to use for server requests (e.g., {'http': 'http://proxy:port', 'https': 'https://proxy:port'}). + :type proxies: Optional[Dict[str, str]] """ _available_ports: List[int] @@ -141,6 +143,9 @@ class LanguageTool: _language: LanguageTag """The language to use (used in requests to the server and in other methods).""" + _proxies: Optional[Dict[str, str]] + """A dictionary of proxies to use for server requests.""" + def __init__( self, language: Optional[str] = None, @@ -151,6 +156,7 @@ def __init__( host: Optional[str] = None, config: Optional[Dict[str, Any]] = None, language_tool_download_version: str = LTP_DOWNLOAD_VERSION, + proxies: Optional[Dict[str, str]] = None, ) -> None: """ Initialize the LanguageTool server. @@ -163,10 +169,19 @@ def __init__( self._available_ports = random.sample(range(8081, 8999), (8999 - 8081)) self._port = self._available_ports.pop() self._server = None + self._proxies = proxies if remote_server and config is not None: err = "Cannot use both remote_server and config parameters." raise ValueError(err) + + if proxies is not None and remote_server is None: + err = ( + "Proxies can only be used with a remote server. " + "Local LanguageTool servers do not require proxy configuration." + ) + raise ValueError(err) + self.config = LanguageToolConfig(config) if config else None if remote_server is not None: @@ -329,6 +344,33 @@ def _spell_checking_categories(self) -> Set[str]: return {"TYPOS"} + @property + def proxies(self) -> Optional[Dict[str, str]]: + """ + Get the proxies used for requests to the server. + + :return: A dictionary of proxies if set, otherwise None. + :rtype: Optional[Dict[str, str]] + """ + return self._proxies + + @proxies.setter + def proxies(self, proxies: Optional[Dict[str, str]]) -> None: + """ + Set the proxies to be used for requests to the server. + + :param proxies: A dictionary of proxies to set, or None to unset. + :type proxies: Optional[Dict[str, str]] + :raises ValueError: If trying to set proxies on a local server. + """ + if proxies is not None and not self._remote: + err = ( + "Proxies can only be used with a remote server. " + "Local LanguageTool servers do not require proxy configuration." + ) + raise ValueError(err) + self._proxies = proxies + def check(self, text: str) -> List[Match]: """ Checks the given text for language issues using the LanguageTool server. @@ -561,6 +603,7 @@ def _query_server( url, params=params, timeout=self._TIMEOUT, + proxies=self.proxies, ) as response: try: return response.json() diff --git a/uv.lock b/uv.lock index bafc1f1..b4a70d4 100644 --- a/uv.lock +++ b/uv.lock @@ -437,15 +437,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674 }, ] -[[package]] -name = "execnet" -version = "2.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708 }, -] - [[package]] name = "furo" version = "2025.9.25" @@ -555,10 +546,6 @@ tests = [ { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "pytest", version = "9.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "pytest-cov" }, - { name = "pytest-rerunfailures", version = "16.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "pytest-rerunfailures", version = "16.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, - { name = "pytest-runner" }, - { name = "pytest-xdist" }, ] types = [ { name = "types-psutil" }, @@ -585,9 +572,6 @@ docs = [ tests = [ { name = "pytest" }, { name = "pytest-cov" }, - { name = "pytest-rerunfailures" }, - { name = "pytest-runner" }, - { name = "pytest-xdist" }, ] types = [ { name = "types-psutil" }, @@ -804,62 +788,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424 }, ] -[[package]] -name = "pytest-rerunfailures" -version = "16.0.1" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -dependencies = [ - { name = "packaging", marker = "python_full_version < '3.10'" }, - { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/26/53/a543a76f922a5337d10df22441af8bf68f1b421cadf9aedf8a77943b81f6/pytest_rerunfailures-16.0.1.tar.gz", hash = "sha256:ed4b3a6e7badb0a720ddd93f9de1e124ba99a0cb13bc88561b3c168c16062559", size = 27612 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/73/67dc14cda1942914e70fbb117fceaf11e259362c517bdadd76b0dd752524/pytest_rerunfailures-16.0.1-py3-none-any.whl", hash = "sha256:0bccc0e3b0e3388275c25a100f7077081318196569a121217688ed05e58984b9", size = 13610 }, -] - -[[package]] -name = "pytest-rerunfailures" -version = "16.1" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.11'", - "python_full_version == '3.10.*'", -] -dependencies = [ - { name = "packaging", marker = "python_full_version >= '3.10'" }, - { name = "pytest", version = "9.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/de/04/71e9520551fc8fe2cf5c1a1842e4e600265b0815f2016b7c27ec85688682/pytest_rerunfailures-16.1.tar.gz", hash = "sha256:c38b266db8a808953ebd71ac25c381cb1981a78ff9340a14bcb9f1b9bff1899e", size = 30889 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/77/54/60eabb34445e3db3d3d874dc1dfa72751bfec3265bd611cb13c8b290adea/pytest_rerunfailures-16.1-py3-none-any.whl", hash = "sha256:5d11b12c0ca9a1665b5054052fcc1084f8deadd9328962745ef6b04e26382e86", size = 14093 }, -] - -[[package]] -name = "pytest-runner" -version = "6.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/7d/60976d532519c3a0b41e06a59ad60949e2be1af937cf02738fec91bfd808/pytest-runner-6.0.1.tar.gz", hash = "sha256:70d4739585a7008f37bf4933c013fdb327b8878a5a69fcbb3316c88882f0f49b", size = 16056 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/23/2b/73982c02d28538b6a1182c0a2faf764ca6a76a6dbe89a69288184051a67b/pytest_runner-6.0.1-py3-none-any.whl", hash = "sha256:ea326ed6f6613992746062362efab70212089a4209c08d67177b3df1c52cd9f2", size = 7186 }, -] - -[[package]] -name = "pytest-xdist" -version = "3.8.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "execnet" }, - { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "pytest", version = "9.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396 }, -] - [[package]] name = "requests" version = "2.32.5"