Skip to content

Commit 571a823

Browse files
authored
Merge pull request #1309 from PyThaiNLP/copilot/remove-auto-download-corpus
Add `PYTHAINLP_OFFLINE` support, `is_offline_mode()`, and `PYTHAINLP_DATA` env var to corpus path handling
2 parents 1827472 + d8185be commit 571a823

28 files changed

Lines changed: 586 additions & 185 deletions

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ See PR for prompt and details.
4040
- Add BLEU, ROUGE, WER, and CER metrics to pythainlp.benchmarks #1295
4141
- Add Attaparse engine to dependency parser
4242
(`dependency_parsing`, engine="attaparse") #1303
43+
- `get_corpus_path()` now respects `PYTHAINLP_OFFLINE` env var (same semantics
44+
as `HF_HUB_OFFLINE`): when set, raises `FileNotFoundError` if the corpus is
45+
not already cached locally; when unset, auto-downloads as before #1306
46+
- Added `pythainlp.is_offline_mode()` helper function (mirrors
47+
`huggingface_hub.is_offline_mode()`) #1306
48+
- `PYTHAINLP_DATA` is now the preferred env var for the data directory
49+
(same pattern as `NLTK_DATA`); `PYTHAINLP_DATA_DIR` is deprecated
50+
and will emit a `DeprecationWarning` #1306
51+
- Callers raise `FileNotFoundError` with download instructions when a corpus
52+
path cannot be resolved (e.g. download failed) #1306
4353
- Improved documentation; code cleanup; more tests
4454

4555
## Version 5.1.2 -> 5.2.0

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,27 @@ please inspect the `[project.optional-dependencies]` section of
7777
PyThaiNLP downloads data (see the data catalog `db.json` at
7878
[pythainlp-corpus](https://github.com/PyThaiNLP/pythainlp-corpus))
7979
to `~/pythainlp-data` by default.
80-
Set the `PYTHAINLP_DATA_DIR` environment variable to override this location.
80+
Set the `PYTHAINLP_DATA` environment variable to override this location.
81+
(`PYTHAINLP_DATA_DIR` is still accepted but deprecated.)
8182

8283
When using PyThaiNLP in distributed computing environments
83-
(e.g., Apache Spark), set the `PYTHAINLP_DATA_DIR` environment variable
84+
(e.g., Apache Spark), set the `PYTHAINLP_DATA` environment variable
8485
inside the function that will be distributed to worker nodes.
8586
See details in
8687
[the documentation](https://pythainlp.org/dev-docs/notes/installation.html).
8788

89+
### Offline mode
90+
91+
Set `PYTHAINLP_OFFLINE=1` to disable automatic corpus downloads.
92+
When this variable is set and a corpus is not already cached locally,
93+
a `FileNotFoundError` is raised instead of attempting a network download.
94+
Use `pythainlp.is_offline_mode()` to check the current state programmatically.
95+
96+
```python
97+
import pythainlp
98+
print(pythainlp.is_offline_mode()) # True if PYTHAINLP_OFFLINE=1
99+
```
100+
88101
## Testing
89102

90103
We test core functionalities on all officially supported Python versions.

README_TH.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,11 @@ pip install "pythainlp[extra1,extra2,...]"
109109
PyThaiNLP ดาวน์โหลดข้อมูล (ดูแค็ตตาล็อกข้อมูล `db.json` ที่
110110
[pythainlp-corpus](https://github.com/PyThaiNLP/pythainlp-corpus))
111111
ไปที่ `~/pythainlp-data` ตามค่าเริ่มต้น
112-
ตั้งค่า environment variable `PYTHAINLP_DATA_DIR` เพื่อเปลี่ยนตำแหน่งนี้
112+
ตั้งค่า environment variable `PYTHAINLP_DATA` เพื่อเปลี่ยนตำแหน่งนี้
113+
(`PYTHAINLP_DATA_DIR` ยังคงใช้ได้แต่เลิกใช้แล้ว)
113114

114115
เมื่อใช้ PyThaiNLP ในสภาพแวดล้อมการคำนวณแบบกระจาย
115-
(เช่น Apache Spark) ให้ตั้งค่า environment variable `PYTHAINLP_DATA_DIR`
116+
(เช่น Apache Spark) ให้ตั้งค่า environment variable `PYTHAINLP_DATA`
116117
ภายในฟังก์ชันที่จะถูกกระจายไปยัง worker nodes
117118
ดูรายละเอียดใน[เอกสาร](https://pythainlp.org/dev-docs/notes/installation.html)
118119

docs/notes/installation.rst

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ Key considerations
8989

9090
2. **Use a writable local directory**: The default data directory (``~/pythainlp-data``) may not be writable on executor nodes. Use a local directory like ``./pythainlp-data`` instead.
9191

92-
3. **Set ``PYTHAINLP_DATA_DIR`` before data access**: Always set the ``PYTHAINLP_DATA_DIR`` environment variable before the first call that reads or writes PyThaiNLP data on each worker.
92+
3. **Set ``PYTHAINLP_DATA`` before data access**: Always set the ``PYTHAINLP_DATA`` environment variable before the first call that reads or writes PyThaiNLP data on each worker.
93+
(``PYTHAINLP_DATA_DIR`` is also accepted for backward compatibility but is deprecated.)
9394

9495
Example usage with Apache Spark
9596
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -104,7 +105,7 @@ Basic example using PySpark RDD::
104105

105106
def tokenize_thai(text):
106107
import os
107-
os.environ['PYTHAINLP_DATA_DIR'] = './pythainlp-data'
108+
os.environ['PYTHAINLP_DATA'] = './pythainlp-data'
108109
from pythainlp.tokenize import word_tokenize
109110
return word_tokenize(text)
110111

@@ -123,7 +124,7 @@ Example using PySpark DataFrame API::
123124
@udf(returnType=ArrayType(StringType()))
124125
def tokenize_udf(text):
125126
import os
126-
os.environ['PYTHAINLP_DATA_DIR'] = './pythainlp-data'
127+
os.environ['PYTHAINLP_DATA'] = './pythainlp-data'
127128
from pythainlp.tokenize import word_tokenize
128129
return word_tokenize(text)
129130

@@ -141,13 +142,30 @@ Note that while the code itself is thread-safe, you still need to configure the
141142
Runtime configurations
142143
----------------------
143144

144-
.. envvar:: PYTHAINLP_DATA_DIR
145+
.. envvar:: PYTHAINLP_DATA
145146

146147
Specifies the location where downloaded data and the corpus database are stored. If the directory does not exist, PyThaiNLP will create it.
147148

148149
By default this is a directory named ``pythainlp-data`` in the user's home directory.
149150

150-
Run ``thainlp data path`` at the command line to display the current `PYTHAINLP_DATA_DIR`.
151+
Run ``thainlp data path`` at the command line to display the current data directory.
152+
153+
.. envvar:: PYTHAINLP_DATA_DIR
154+
155+
.. deprecated::
156+
Use :envvar:`PYTHAINLP_DATA` instead. Setting ``PYTHAINLP_DATA_DIR`` triggers a
157+
:class:`DeprecationWarning` at runtime. If both ``PYTHAINLP_DATA`` and ``PYTHAINLP_DATA_DIR``
158+
are set simultaneously, PyThaiNLP raises :exc:`ValueError`.
159+
160+
.. envvar:: PYTHAINLP_OFFLINE
161+
162+
When set to a truthy value (``1``, ``true``, ``yes``, ``on``), PyThaiNLP operates in
163+
*offline mode*: corpus downloads are disabled, and :func:`pythainlp.corpus.get_corpus_path`
164+
raises :exc:`FileNotFoundError` for any corpus that is not already cached locally.
165+
166+
Use :func:`pythainlp.is_offline_mode` to check the current state programmatically.
167+
168+
This follows the same convention as ``HF_HUB_OFFLINE`` in `huggingface_hub`.
151169

152170
.. envvar:: PYTHAINLP_READ_MODE
153171

@@ -158,11 +176,11 @@ Installation FAQ
158176

159177
Q: How do I set environment variables on each executor node in a distributed environment?
160178

161-
A: When using PyThaiNLP in distributed computing environments like Apache Spark, you need to set the ``PYTHAINLP_DATA_DIR`` environment variable inside the function that will be distributed to executor nodes. For example::
179+
A: When using PyThaiNLP in distributed computing environments like Apache Spark, you need to set the ``PYTHAINLP_DATA`` environment variable inside the function that will be distributed to executor nodes. For example::
162180

163181
def tokenize_thai(text):
164182
import os
165-
os.environ['PYTHAINLP_DATA_DIR'] = './pythainlp-data'
183+
os.environ['PYTHAINLP_DATA'] = './pythainlp-data'
166184
from pythainlp.tokenize import word_tokenize
167185
return word_tokenize(text)
168186

pythainlp/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
__all__: list[str] = [
5656
"collate",
5757
"correct",
58+
"is_offline_mode",
5859
"pos_tag",
5960
"romanize",
6061
"spell",
@@ -76,5 +77,6 @@
7677
subword_tokenize,
7778
word_tokenize,
7879
)
80+
from pythainlp.tools.path import is_offline_mode
7981
from pythainlp.transliterate import romanize, transliterate
8082
from pythainlp.util import collate, thai_strftime

pythainlp/augment/word2vec/ltw2v.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ def tokenizer(self, text: str) -> list[str]:
3232

3333
def load_w2v(self) -> None: # insert substitute
3434
"""Load LTW2V's word2vec model"""
35-
if self.ltw2v_wv is None:
36-
raise ValueError(
37-
"LTW2V word2vec model not found. "
38-
"Please download it first using pythainlp.corpus.download('ltw2v_wv')"
35+
if not self.ltw2v_wv:
36+
raise FileNotFoundError(
37+
"corpus-not-found name='ltw2v_wv'\n"
38+
" Corpus 'ltw2v_wv' not found.\n"
39+
" Python: pythainlp.corpus.download('ltw2v_wv')\n"
40+
" CLI: thainlp data get ltw2v_wv"
3941
)
4042
self.aug: Word2VecAug = Word2VecAug(
4143
self.ltw2v_wv, self.tokenizer, type="binary"

pythainlp/augment/word2vec/thai2fit.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ def tokenizer(self, text: str) -> list[str]:
3333

3434
def load_w2v(self) -> None:
3535
"""Load Thai2Fit's word2vec model"""
36-
if self.thai2fit_wv is None:
37-
raise ValueError(
38-
"Thai2Fit word2vec model not found. "
39-
"Please download it first using pythainlp.corpus.download('thai2fit_wv')"
36+
if not self.thai2fit_wv:
37+
raise FileNotFoundError(
38+
"corpus-not-found name='thai2fit_wv'\n"
39+
" Corpus 'thai2fit_wv' not found.\n"
40+
" Python: pythainlp.corpus.download('thai2fit_wv')\n"
41+
" CLI: thainlp data get thai2fit_wv"
4042
)
4143
self.aug: Word2VecAug = Word2VecAug(
4244
self.thai2fit_wv, self.tokenizer, type="binary"

pythainlp/cli/data.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ def __init__(self, argv: Sequence[str]) -> None:
3333
"Current data path:\n\n"
3434
f"{get_pythainlp_data_path()}\n\n"
3535
"To change PyThaiNLP data path, set the operating system's\n"
36-
"PYTHAINLP_DATA_DIR environment variable.\n\n"
36+
"PYTHAINLP_DATA environment variable.\n"
37+
"(PYTHAINLP_DATA_DIR is also accepted but deprecated.)\n\n"
3738
"For more information about corpora that PyThaiNLP use, see:\n"
3839
"https://github.com/PyThaiNLP/pythainlp-corpus/\n\n"
3940
"--"

0 commit comments

Comments
 (0)