Skip to content

Commit a48475d

Browse files
hive-botclaude
andcommitted
feat: deprecate downloads without output_file and raise the default chunk_size
translate_document_download() and download_translation_memory_export() now emit a DeprecationWarning when called without output_file; they still return the streaming requests.Response. Their default chunk_size is 64 KiB instead of 1 byte, so writing to output_file no longer makes one write call per byte. The written content is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 8d416d0 commit a48475d

6 files changed

Lines changed: 63 additions & 21 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6262
`/v2/glossary-language-pairs` endpoints. Public signatures and return
6363
types are unchanged, but the returned language lists may now include
6464
additional languages.
65+
- The default `chunk_size` of `translate_document_download()` and
66+
`download_translation_memory_export()` is now 64 KiB instead of 1 byte, so
67+
downloads into `output_file` no longer write one byte per call. The written
68+
content is unchanged; an explicit `chunk_size` still applies.
6569

6670
### Deprecated
71+
- Calling `translate_document_download()` or
72+
`download_translation_memory_export()` without `output_file` now emits a
73+
`DeprecationWarning`. It still returns the streaming `requests.Response`; in
74+
the next major version `output_file` will be required and both methods will
75+
return `None`.
6776
- Passing `skip_language_check` to `Translator()` or `DeepLClient()`, or
6877
`skip_cache` to `get_source_languages()` or `get_target_languages()`, now
6978
emits a `DeprecationWarning`. Both parameters have no effect and will be

‎README.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,12 @@ these steps individually, you can instead use the following functions directly:
342342
`translate_document_wait_until_done()`), and
343343
- `translate_document_download()`
344344

345+
`translate_document_download()` writes the translated document to the
346+
file-like object given as `output_file`, in chunks of `chunk_size` bytes
347+
(default 64 KiB). Calling it without `output_file` returns the streaming
348+
`requests.Response` instead; this is deprecated, emits a `DeprecationWarning`,
349+
and `output_file` will be required in the next major version.
350+
345351
#### Document translation options
346352

347353
In addition to the input file, output file, `source_lang` and `target_lang`
@@ -1140,6 +1146,11 @@ with open("/path/to/exported.tmx", "wb") as output_file:
11401146
)
11411147
```
11421148

1149+
`download_translation_memory_export()` writes in chunks of `chunk_size` bytes
1150+
(default 64 KiB). Calling it without `output_file` returns the streaming
1151+
`requests.Response` instead; this is deprecated, emits a `DeprecationWarning`,
1152+
and `output_file` will be required in the next major version.
1153+
11431154
#### Deleting a translation memory
11441155

11451156
Use `delete_translation_memory()` to delete a translation memory by ID.

‎deepl/deepl_client.py‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@
2626
TranslationMemorySegments,
2727
)
2828
from deepl.exceptions import DeepLException
29-
from deepl.translator import Translator, _warn_skip_language_check
29+
from deepl.translator import (
30+
Translator,
31+
_DOWNLOAD_CHUNK_SIZE,
32+
_warn_download_without_output_file,
33+
_warn_skip_language_check,
34+
)
3035
from deepl import util
3136
import os
3237
import pathlib
@@ -1712,17 +1717,18 @@ def download_translation_memory_export(
17121717
self,
17131718
job: TranslationMemoryJob,
17141719
output_file: Union[BinaryIO, Any, None] = None,
1715-
chunk_size: int = 1,
1720+
chunk_size: int = _DOWNLOAD_CHUNK_SIZE,
17161721
) -> Optional[requests.Response]:
17171722
"""Downloads the TMX file of a completed export job.
17181723
17191724
:param job: Completed export TranslationMemoryJob carrying the
17201725
download URL.
1721-
:param output_file: (Optional) File-like object to store the
1722-
downloaded TMX file. If not provided, use iter_content() on the
1723-
returned response object to read streamed file data.
1724-
:param chunk_size: (Optional) Size of chunk in bytes for streaming.
1725-
Only used if output_file is specified.
1726+
:param output_file: File-like object to store the downloaded TMX
1727+
file. Omitting it is deprecated: the requests.Response is then
1728+
returned instead, and iter_content() reads the streamed file data.
1729+
In the next major version output_file will be required.
1730+
:param chunk_size: (Optional) Size of chunk in bytes for streaming,
1731+
default 64 KiB. Only used if output_file is specified.
17261732
:return: None if output_file is specified, otherwise the
17271733
requests.Response.
17281734
"""
@@ -1745,6 +1751,7 @@ def download_translation_memory_export(
17451751
for chunk in content.iter_content(chunk_size=chunk_size):
17461752
output_file.write(chunk)
17471753
return None
1754+
_warn_download_without_output_file()
17481755
return content
17491756

17501757
def import_translation_memory_from_filepath(

‎deepl/translator.py‎

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ def _warn_skip_language_check() -> None:
5050
)
5151

5252

53+
# Default chunk size for writing downloads into output_file.
54+
_DOWNLOAD_CHUNK_SIZE = 64 * 1024
55+
56+
57+
def _warn_download_without_output_file() -> None:
58+
warnings.warn(
59+
"returning the response is deprecated; pass output_file",
60+
DeprecationWarning,
61+
stacklevel=3,
62+
)
63+
64+
5365
def _warn_skip_cache() -> None:
5466
warnings.warn(
5567
"skip_cache is deprecated and has no effect",
@@ -932,20 +944,18 @@ def translate_document_download(
932944
self,
933945
handle: DocumentHandle,
934946
output_file: Union[TextIO, BinaryIO, Any, None] = None,
935-
chunk_size: int = 1,
947+
chunk_size: int = _DOWNLOAD_CHUNK_SIZE,
936948
) -> Optional[requests.Response]:
937949
"""Downloads the translated document for the request associated with
938-
given handle and returns a response object for streaming the data. Call
939-
iter_content() on the response object to read streamed file data.
940-
Alternatively, a file-like object may be given as output_file where the
941-
complete file will be downloaded and written to.
950+
given handle and writes it to the file-like object output_file.
942951
943952
:param handle: DocumentHandle associated with request.
944-
:param output_file: (Optional) File-like object to store downloaded
945-
document. If not provided, use iter_content() on the returned
946-
response object to read streamed file data.
947-
:param chunk_size: (Optional) Size of chunk in bytes for streaming.
948-
Only used if output_file is specified.
953+
:param output_file: File-like object to store downloaded document.
954+
Omitting it is deprecated: the requests.Response is then returned
955+
instead, and iter_content() reads the streamed file data. In the
956+
next major version output_file will be required.
957+
:param chunk_size: (Optional) Size of chunk in bytes for streaming,
958+
default 64 KiB. Only used if output_file is specified.
949959
:return: None if output_file is specified, otherwise the
950960
requests.Response will be returned.
951961
"""
@@ -973,6 +983,7 @@ def translate_document_download(
973983
output_file.write(chunk)
974984
return None
975985
else:
986+
_warn_download_without_output_file()
976987
return response
977988

978989
def get_source_languages(

‎tests/offline/test_translate_document.py‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,10 +359,13 @@ def test_raises_when_downloading_document_that_is_not_ready(
359359
assert exc_info.value.http_status_code == 503
360360

361361

362-
def test_returns_streaming_response_when_downloading_without_file(mocked):
362+
def test_warns_and_returns_streaming_response_when_downloading_without_file(
363+
mocked,
364+
):
363365
reply_with_result(mocked, b"translated")
364366

365-
response = make_translator().translate_document_download(HANDLE)
367+
with pytest.warns(DeprecationWarning, match="pass output_file"):
368+
response = make_translator().translate_document_download(HANDLE)
366369

367370
assert b"".join(response.iter_content(chunk_size=4)) == b"translated"
368371

‎tests/offline/test_translation_memories.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,15 +540,16 @@ def test_downloads_export_without_authorization_into_file_object(mocked):
540540
assert output.getvalue() == b"<tmx/>"
541541

542542

543-
def test_returns_streaming_response_when_downloading_export_without_file(
543+
def test_warns_and_returns_response_when_downloading_export_without_file(
544544
mocked,
545545
):
546546
mocked.get(DOWNLOAD_URL, body=b"<tmx/>", match=storage_request())
547547
job = TranslationMemoryJob.from_json(
548548
job_json("completed", "export", download_url=DOWNLOAD_URL)
549549
)
550550

551-
response = make_deepl_client().download_translation_memory_export(job)
551+
with pytest.warns(DeprecationWarning, match="pass output_file"):
552+
response = make_deepl_client().download_translation_memory_export(job)
552553

553554
assert b"".join(response.iter_content(chunk_size=3)) == b"<tmx/>"
554555

0 commit comments

Comments
 (0)