sapling-py 4.3.0__tar.gz → 4.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sapling_py-4.3.0/sapling_py.egg-info → sapling_py-4.4.0}/PKG-INFO +3 -3
- {sapling_py-4.3.0 → sapling_py-4.4.0}/README.md +2 -2
- {sapling_py-4.3.0 → sapling_py-4.4.0}/sapling/client.py +57 -0
- sapling_py-4.4.0/sapling/version.py +1 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0/sapling_py.egg-info}/PKG-INFO +3 -3
- {sapling_py-4.3.0 → sapling_py-4.4.0}/sapling_py.egg-info/SOURCES.txt +2 -1
- sapling_py-4.4.0/test/test_translate.py +81 -0
- sapling_py-4.3.0/sapling/version.py +0 -1
- {sapling_py-4.3.0 → sapling_py-4.4.0}/LICENSE +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/pyproject.toml +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/sapling/__init__.py +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/sapling_py.egg-info/dependency_links.txt +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/sapling_py.egg-info/requires.txt +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/sapling_py.egg-info/top_level.txt +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/setup.cfg +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/setup.py +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/test/test_classify.py +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/test/test_client.py +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/test/test_extract.py +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/test/test_pii.py +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/test/test_safety.py +0 -0
- {sapling_py-4.3.0 → sapling_py-4.4.0}/test/test_seo.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sapling-py
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.0
|
|
4
4
|
Summary: Sapling Python Client
|
|
5
5
|
Author-email: Sapling Intelligence <info@sapling.ai>
|
|
6
6
|
License: Apache License 2.0
|
|
@@ -31,8 +31,8 @@ Compare against leading grammar checking tools and APIs like Grammarly (Grammerl
|
|
|
31
31
|
|
|
32
32
|
Sapling is a toolkit for helping developers build language model-powered applications.
|
|
33
33
|
The API provides spelling and grammar checking, autocomplete, tone detection, rephrasing, AI detection,
|
|
34
|
-
zero-shot text classification, structured data extraction, PII detection and redaction,
|
|
35
|
-
scoring, SEO analysis, and more.
|
|
34
|
+
zero-shot text classification, structured data extraction, translation, PII detection and redaction,
|
|
35
|
+
content safety scoring, SEO analysis, and more.
|
|
36
36
|
|
|
37
37
|
Key Features:
|
|
38
38
|
- **60% More Corrections**: Outperforms [competing solutions](https://sapling.ai/comparison/api#sapling) at similar accuracy levels using state-of-the-art generative AI models.
|
|
@@ -9,8 +9,8 @@ Compare against leading grammar checking tools and APIs like Grammarly (Grammerl
|
|
|
9
9
|
|
|
10
10
|
Sapling is a toolkit for helping developers build language model-powered applications.
|
|
11
11
|
The API provides spelling and grammar checking, autocomplete, tone detection, rephrasing, AI detection,
|
|
12
|
-
zero-shot text classification, structured data extraction, PII detection and redaction,
|
|
13
|
-
scoring, SEO analysis, and more.
|
|
12
|
+
zero-shot text classification, structured data extraction, translation, PII detection and redaction,
|
|
13
|
+
content safety scoring, SEO analysis, and more.
|
|
14
14
|
|
|
15
15
|
Key Features:
|
|
16
16
|
- **60% More Corrections**: Outperforms [competing solutions](https://sapling.ai/comparison/api#sapling) at similar accuracy levels using state-of-the-art generative AI models.
|
|
@@ -718,6 +718,63 @@ class SaplingClient:
|
|
|
718
718
|
data['context'] = context
|
|
719
719
|
return self._request(url, data)
|
|
720
720
|
|
|
721
|
+
def translate(
|
|
722
|
+
self,
|
|
723
|
+
text,
|
|
724
|
+
target_lang,
|
|
725
|
+
source_lang=None,
|
|
726
|
+
formality=None,
|
|
727
|
+
):
|
|
728
|
+
'''
|
|
729
|
+
Translates text into a target language with an LLM, preserving line
|
|
730
|
+
breaks, markup and placeholders in place. The response reports the
|
|
731
|
+
language the text was actually written in (detected, not assumed from
|
|
732
|
+
the hint).
|
|
733
|
+
|
|
734
|
+
Example::
|
|
735
|
+
|
|
736
|
+
client.translate(
|
|
737
|
+
'Hello world.\\nSee you at 5pm.',
|
|
738
|
+
target_lang='fr',
|
|
739
|
+
)
|
|
740
|
+
# {'translation': 'Bonjour le monde.\\nÀ 17h.',
|
|
741
|
+
# 'source_lang': 'en', 'source_lang_name': 'English',
|
|
742
|
+
# 'target_lang': 'fr', 'target_lang_name': 'French'}
|
|
743
|
+
|
|
744
|
+
:param text: Text to translate, up to 5,000 characters. Markup and
|
|
745
|
+
whitespace are preserved, not stripped.
|
|
746
|
+
:type text: str
|
|
747
|
+
:param target_lang: Language to translate into: an ISO 639 code
|
|
748
|
+
(``'fr'``, ``'zh-TW'``) or an English language name
|
|
749
|
+
(``'French'``). Region variants ``zh-CN``/``zh-TW``/``zh-HK``,
|
|
750
|
+
``pt-BR``/``pt-PT``, ``en-GB``/``en-US``, ``fr-CA`` and ``es-419``
|
|
751
|
+
are supported as targets.
|
|
752
|
+
:type target_lang: str
|
|
753
|
+
:param source_lang: Optional hint for the source language, same forms
|
|
754
|
+
as ``target_lang``. The text itself wins if they disagree.
|
|
755
|
+
:type source_lang: str
|
|
756
|
+
:param formality: Optional register: ``'formal'`` (vous/Sie/usted) or
|
|
757
|
+
``'informal'`` (tu/du/tú). Omit for the model default.
|
|
758
|
+
:type formality: str
|
|
759
|
+
:rtype: dict
|
|
760
|
+
:return:
|
|
761
|
+
- translation: The translated text, structure preserved.
|
|
762
|
+
- source_lang / source_lang_name: The detected source language
|
|
763
|
+
(``'und'`` and ``None`` when undetermined).
|
|
764
|
+
- target_lang / target_lang_name: The normalized target.
|
|
765
|
+
'''
|
|
766
|
+
url = self.url_endpoint + 'translate'
|
|
767
|
+
data = {
|
|
768
|
+
'key': self.api_key,
|
|
769
|
+
'text': text,
|
|
770
|
+
'target_lang': target_lang,
|
|
771
|
+
}
|
|
772
|
+
if source_lang is not None:
|
|
773
|
+
data['source_lang'] = source_lang
|
|
774
|
+
if formality is not None:
|
|
775
|
+
data['formality'] = formality
|
|
776
|
+
return self._request(url, data)
|
|
777
|
+
|
|
721
778
|
def tone(
|
|
722
779
|
self,
|
|
723
780
|
text,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '4.4.0'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sapling-py
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.0
|
|
4
4
|
Summary: Sapling Python Client
|
|
5
5
|
Author-email: Sapling Intelligence <info@sapling.ai>
|
|
6
6
|
License: Apache License 2.0
|
|
@@ -31,8 +31,8 @@ Compare against leading grammar checking tools and APIs like Grammarly (Grammerl
|
|
|
31
31
|
|
|
32
32
|
Sapling is a toolkit for helping developers build language model-powered applications.
|
|
33
33
|
The API provides spelling and grammar checking, autocomplete, tone detection, rephrasing, AI detection,
|
|
34
|
-
zero-shot text classification, structured data extraction, PII detection and redaction,
|
|
35
|
-
scoring, SEO analysis, and more.
|
|
34
|
+
zero-shot text classification, structured data extraction, translation, PII detection and redaction,
|
|
35
|
+
content safety scoring, SEO analysis, and more.
|
|
36
36
|
|
|
37
37
|
Key Features:
|
|
38
38
|
- **60% More Corrections**: Outperforms [competing solutions](https://sapling.ai/comparison/api#sapling) at similar accuracy levels using state-of-the-art generative AI models.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
import responses
|
|
5
|
+
|
|
6
|
+
from sapling import SaplingClient, SaplingError
|
|
7
|
+
|
|
8
|
+
API_KEY = 'a' * 32
|
|
9
|
+
BASE = 'https://api.sapling.ai/api/v1/'
|
|
10
|
+
|
|
11
|
+
TEXT = 'Hello world.\nSee you at 5pm.'
|
|
12
|
+
|
|
13
|
+
TRANSLATE_RESPONSE = {
|
|
14
|
+
'translation': 'Bonjour le monde.\nÀ 17h.',
|
|
15
|
+
'source_lang': 'en',
|
|
16
|
+
'source_lang_name': 'English',
|
|
17
|
+
'target_lang': 'fr',
|
|
18
|
+
'target_lang_name': 'French',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@pytest.fixture
|
|
23
|
+
def client():
|
|
24
|
+
return SaplingClient(api_key=API_KEY)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _last_request_body():
|
|
28
|
+
return json.loads(responses.calls[-1].request.body)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@responses.activate
|
|
32
|
+
def test_translate_returns_json_and_sends_key(client):
|
|
33
|
+
responses.add(responses.POST, BASE + 'translate',
|
|
34
|
+
json=TRANSLATE_RESPONSE, status=200)
|
|
35
|
+
result = client.translate(TEXT, target_lang='fr')
|
|
36
|
+
assert result == TRANSLATE_RESPONSE
|
|
37
|
+
body = _last_request_body()
|
|
38
|
+
assert body == {'key': API_KEY, 'text': TEXT, 'target_lang': 'fr'}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@responses.activate
|
|
42
|
+
def test_translate_posts_to_translate_endpoint(client):
|
|
43
|
+
responses.add(responses.POST, BASE + 'translate',
|
|
44
|
+
json=TRANSLATE_RESPONSE, status=200)
|
|
45
|
+
client.translate(TEXT, target_lang='fr')
|
|
46
|
+
assert responses.calls[-1].request.url == BASE + 'translate'
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@responses.activate
|
|
50
|
+
def test_translate_optional_params_sent_only_when_given(client):
|
|
51
|
+
responses.add(responses.POST, BASE + 'translate',
|
|
52
|
+
json=TRANSLATE_RESPONSE, status=200)
|
|
53
|
+
client.translate(TEXT, target_lang='fr')
|
|
54
|
+
body = _last_request_body()
|
|
55
|
+
assert 'source_lang' not in body
|
|
56
|
+
assert 'formality' not in body
|
|
57
|
+
|
|
58
|
+
client.translate(TEXT, target_lang='fr',
|
|
59
|
+
source_lang='en', formality='formal')
|
|
60
|
+
body = _last_request_body()
|
|
61
|
+
assert body['source_lang'] == 'en'
|
|
62
|
+
assert body['formality'] == 'formal'
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@responses.activate
|
|
66
|
+
def test_translate_accepts_names_and_region_variants(client):
|
|
67
|
+
responses.add(responses.POST, BASE + 'translate',
|
|
68
|
+
json=dict(TRANSLATE_RESPONSE, target_lang='zh-TW',
|
|
69
|
+
target_lang_name='Traditional Chinese'),
|
|
70
|
+
status=200)
|
|
71
|
+
result = client.translate(TEXT, target_lang='Traditional Chinese')
|
|
72
|
+
assert result['target_lang'] == 'zh-TW'
|
|
73
|
+
assert _last_request_body()['target_lang'] == 'Traditional Chinese'
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@responses.activate
|
|
77
|
+
def test_translate_http_error_raises_sapling_error(client):
|
|
78
|
+
responses.add(responses.POST, BASE + 'translate',
|
|
79
|
+
json={'msg': 'Unknown language: "Klingon".'}, status=400)
|
|
80
|
+
with pytest.raises(SaplingError):
|
|
81
|
+
client.translate(TEXT, target_lang='Klingon')
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '4.3.0'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|