Skip to content

Commit 934d9c4

Browse files
authored
feat: added new LT config values and replaced asserts in prod by if/raise (jxmorris12#121)
* feat (config_file): added new LT config values and replaced asserts in prod by if/raise * feat (pyproject): added setuptools config to locate package * docs (README): corrected error in doc (cant connect to remote using 0.0.0.0)
1 parent 3576f71 commit 934d9c4

File tree

6 files changed

+60
-12
lines changed

6 files changed

+60
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ You can run LanguageTool on one host and connect to it from another. This is us
179179
#### client
180180
```python
181181
>>> import language_tool_python
182-
>>> lang_tool = language_tool_python.LanguageTool('en-US', remote_server='http://0.0.0.0:8081')
182+
>>> lang_tool = language_tool_python.LanguageTool('en-US', remote_server='http://127.0.0.1:8081')
183183
>>>
184184
>>>
185185
>>> lang_tool.check('helo darknes my old frend')

language_tool_python/config_file.py

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,46 @@
3131
"maxPipelinePoolSize",
3232
"pipelineExpireTimeInSeconds",
3333
"pipelinePrewarming",
34+
"trustXForwardForHeader",
35+
"suggestionsEnabled",
3436
}
3537

3638

39+
def _is_lang_key(key: str) -> bool:
40+
"""
41+
Check if a given key is a valid language key.
42+
A valid language key must follow one of these formats:
43+
44+
- lang-<code> where code is a non-empty language code
45+
- lang-<code>-dictPath where code is a non-empty language code
46+
47+
:param key: The key string to validate
48+
:type key: str
49+
:return: True if the key is a valid language key, False otherwise
50+
:rtype: bool
51+
"""
52+
if not key.startswith("lang-"):
53+
return False
54+
55+
parts = key.split("-")
56+
return (len(parts) == 2 and len(parts[1]) > 0) or (
57+
len(parts) == 3 and len(parts[1]) > 0 and parts[2] == "dictPath"
58+
)
59+
60+
61+
def _validate_config_keys(config: Dict[str, Any]) -> None:
62+
"""
63+
Validate that all keys in the configuration dictionary are allowed.
64+
65+
:param config: Dictionary containing configuration keys and values.
66+
:type config: Dict[str, Any]
67+
:raises ValueError: If a key is found that is not in ALLOWED_CONFIG_KEYS and is not a language key.
68+
"""
69+
for key in config:
70+
if key not in ALLOWED_CONFIG_KEYS and not _is_lang_key(key):
71+
raise ValueError(f"unexpected key in config: {key}")
72+
73+
3774
class LanguageToolConfig:
3875
"""
3976
Configuration class for LanguageTool.
@@ -53,17 +90,23 @@ def __init__(self, config: Dict[str, Any]):
5390
"""
5491
Initialize the LanguageToolConfig object.
5592
"""
56-
assert set(config.keys()) <= ALLOWED_CONFIG_KEYS, (
57-
f"unexpected keys in config: {set(config.keys()) - ALLOWED_CONFIG_KEYS}"
58-
)
59-
assert len(config), "config cannot be empty"
93+
if not config:
94+
raise ValueError("config cannot be empty")
95+
_validate_config_keys(config)
96+
6097
self.config = config
6198

6299
if "disabledRuleIds" in self.config:
63100
self.config["disabledRuleIds"] = ",".join(self.config["disabledRuleIds"])
64101
if "blockedReferrers" in self.config:
65102
self.config["blockedReferrers"] = ",".join(self.config["blockedReferrers"])
66-
for key in ["pipelineCaching", "premiumOnly", "pipelinePrewarming"]:
103+
for key in [
104+
"pipelineCaching",
105+
"premiumOnly",
106+
"pipelinePrewarming",
107+
"trustXForwardForHeader",
108+
"suggestionsEnabled",
109+
]:
67110
if key in self.config:
68111
self.config[key] = str(bool(self.config[key])).lower()
69112

language_tool_python/download_lt.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def download_lt(language_tool_version: Optional[str] = LTP_DOWNLOAD_VERSION) ->
239239
specified, the default version defined by
240240
LTP_DOWNLOAD_VERSION is used.
241241
:type language_tool_version: Optional[str]
242-
:raises AssertionError: If the download folder is not a directory.
242+
:raises PathError: If the download folder is not a directory.
243243
:raises ValueError: If the specified version format is invalid.
244244
"""
245245

@@ -255,7 +255,8 @@ def download_lt(language_tool_version: Optional[str] = LTP_DOWNLOAD_VERSION) ->
255255
# Make download path, if it doesn't exist.
256256
os.makedirs(download_folder, exist_ok=True)
257257

258-
assert os.path.isdir(download_folder)
258+
if not os.path.isdir(download_folder):
259+
raise PathError(f"Download folder {download_folder} is not a directory.")
259260
old_path_list = find_existing_language_tool_downloads(download_folder)
260261

261262
if language_tool_version:

language_tool_python/server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ def __init__(
117117
self._new_spellings_persist = new_spellings_persist
118118
self._host = host or socket.gethostbyname("localhost")
119119

120-
if remote_server:
121-
assert config is None, "cannot pass config file to remote server"
120+
if remote_server and config is not None:
121+
raise ValueError("Cannot use both remote_server and config parameters.")
122122
self.config = LanguageToolConfig(config) if config else None
123123

124124
if remote_server is not None:

language_tool_python/utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,10 @@ def kill_process_force(
314314
:type pid: Optional[int]
315315
:param proc: A psutil.Process object representing the process to be killed. Either `pid` or `proc` must be provided.
316316
:type proc: Optional[psutil.Process]
317-
:raises AssertionError: If neither `pid` nor `proc` is provided.
317+
:raises ValueError: If neither `pid` nor `proc` is provided.
318318
"""
319-
assert any([pid, proc]), "Must pass either pid or proc"
319+
if not any([pid, proc]):
320+
raise ValueError("Must pass either pid or proc")
320321
try:
321322
proc = psutil.Process(pid) if proc is None else proc
322323
except psutil.NoSuchProcess:

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,8 @@ language_tool_python = "language_tool_python.__main__:main"
4949
requires = ["setuptools>=61.0", "wheel"]
5050
build-backend = "setuptools.build_meta"
5151

52+
[tool.setuptools]
53+
packages = { find = { include = ["language_tool_python*"] } }
54+
5255
[tool.ruff.lint]
5356
select = ["F", "W", "I", "B", "SIM", "RET", "Q"]

0 commit comments

Comments
 (0)