Skip to content

Commit 6e6ac5b

Browse files
committed
fix: fixing a failure in tests when there is a ratelimit in the public API
1 parent 5f1751f commit 6e6ac5b

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

language_tool_python/server.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
parse_url, get_locale_language,
2424
get_language_tool_directory, get_server_cmd,
2525
FAILSAFE_LANGUAGE, startupinfo,
26-
LanguageToolError, ServerError, PathError,
26+
LanguageToolError, ServerError, PathError, RateLimitError,
2727
kill_process_force
2828
)
2929

@@ -485,6 +485,11 @@ def _query_server(
485485
)
486486
print(response)
487487
print(response.content)
488+
if response.status_code == 426:
489+
raise RateLimitError(
490+
'You have exceeded the rate limit for the free '
491+
'LanguageTool API. Please try again later.'
492+
)
488493
raise LanguageToolError(response.content.decode())
489494
except (IOError, http.client.HTTPException) as e:
490495
if self._remote is False:

language_tool_python/utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ class PathError(LanguageToolError):
7373
pass
7474

7575

76+
class RateLimitError(LanguageToolError):
77+
"""
78+
Exception raised for errors related to rate limiting in the LanguageTool server.
79+
This exception is a subclass of `LanguageToolError` and is used to indicate
80+
issues such as exceeding the allowed number of requests to the public API without a key.
81+
"""
82+
pass
83+
84+
7685
def parse_url(url_str: str) -> str:
7786
"""
7887
Parse the given URL string and ensure it has a scheme.

tests/test_major_functionality.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import pytest
66

7-
from language_tool_python.utils import LanguageToolError
7+
from language_tool_python.utils import LanguageToolError, RateLimitError
88

99

1010
def test_langtool_load():
@@ -188,9 +188,13 @@ def test_uk_typo():
188188

189189
def test_remote_es():
190190
import language_tool_python
191-
tool = language_tool_python.LanguageToolPublicAPI('es')
192-
es_text = 'Escriba un texto aquí. LanguageTool le ayudará a afrentar algunas dificultades propias de la escritura. Se a hecho un esfuerzo para detectar errores tipográficos, ortograficos y incluso gramaticales. También algunos errores de estilo, a grosso modo.'
193-
matches = tool.check(es_text)
191+
try:
192+
tool = language_tool_python.LanguageToolPublicAPI('es')
193+
es_text = 'Escriba un texto aquí. LanguageTool le ayudará a afrentar algunas dificultades propias de la escritura. Se a hecho un esfuerzo para detectar errores tipográficos, ortograficos y incluso gramaticales. También algunos errores de estilo, a grosso modo.'
194+
matches = tool.check(es_text)
195+
except RateLimitError:
196+
print("Rate limit error: skipping test about public API.")
197+
return
194198
assert str(matches) == """[Match({'ruleId': 'AFRENTAR_DIFICULTADES', 'message': 'Confusión entre «afrontar» y «afrentar».', 'replacements': ['afrontar'], 'offsetInContext': 43, 'context': '...n texto aquí. LanguageTool le ayudará a afrentar algunas dificultades propias de la escr...', 'offset': 49, 'errorLength': 8, 'category': 'INCORRECT_EXPRESSIONS', 'ruleIssueType': 'grammar', 'sentence': 'LanguageTool le ayudará a afrentar algunas dificultades propias de la escritura.'}), Match({'ruleId': 'PRON_HABER_PARTICIPIO', 'message': 'El v. ‘haber’ se escribe con hache.', 'replacements': ['ha'], 'offsetInContext': 43, 'context': '...ificultades propias de la escritura. Se a hecho un esfuerzo para detectar errores...', 'offset': 107, 'errorLength': 1, 'category': 'MISSPELLING', 'ruleIssueType': 'misspelling', 'sentence': 'Se a hecho un esfuerzo para detectar errores tipográficos, ortograficos y incluso gramaticales.'}), Match({'ruleId': 'MORFOLOGIK_RULE_ES', 'message': 'Se ha encontrado un posible error ortográfico.', 'replacements': ['ortográficos', 'ortográficas', 'ortográfico', 'orográficos', 'ortografiaos', 'ortografíeos'], 'offsetInContext': 43, 'context': '...rzo para detectar errores tipográficos, ortograficos y incluso gramaticales. También algunos...', 'offset': 163, 'errorLength': 12, 'category': 'TYPOS', 'ruleIssueType': 'misspelling', 'sentence': 'Se a hecho un esfuerzo para detectar errores tipográficos, ortograficos y incluso gramaticales.'}), Match({'ruleId': 'Y_E_O_U', 'message': 'Cuando precede a palabras que comienzan por ‘i’, la conjunción ‘y’ se transforma en ‘e’.', 'replacements': ['e'], 'offsetInContext': 43, 'context': '...ctar errores tipográficos, ortograficos y incluso gramaticales. También algunos e...', 'offset': 176, 'errorLength': 1, 'category': 'GRAMMAR', 'ruleIssueType': 'grammar', 'sentence': 'Se a hecho un esfuerzo para detectar errores tipográficos, ortograficos y incluso gramaticales.'}), Match({'ruleId': 'GROSSO_MODO', 'message': 'Esta expresión latina se usa sin preposición.', 'replacements': ['grosso modo'], 'offsetInContext': 43, 'context': '...les. También algunos errores de estilo, a grosso modo.', 'offset': 235, 'errorLength': 13, 'category': 'GRAMMAR', 'ruleIssueType': 'grammar', 'sentence': 'También algunos errores de estilo, a grosso modo.'})]"""
195199
tool.close()
196200

0 commit comments

Comments
 (0)