sapling-py 4.0.2__tar.gz → 4.1.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.1.0/PKG-INFO +102 -0
- sapling_py-4.1.0/README.md +70 -0
- {sapling_py-4.0.2 → sapling_py-4.1.0}/sapling/__init__.py +2 -1
- {sapling_py-4.0.2 → sapling_py-4.1.0}/sapling/client.py +239 -84
- sapling_py-4.1.0/sapling/version.py +1 -0
- sapling_py-4.1.0/sapling_py.egg-info/PKG-INFO +102 -0
- {sapling_py-4.0.2 → sapling_py-4.1.0}/sapling_py.egg-info/SOURCES.txt +2 -1
- sapling_py-4.1.0/sapling_py.egg-info/requires.txt +5 -0
- {sapling_py-4.0.2 → sapling_py-4.1.0}/sapling_py.egg-info/top_level.txt +0 -1
- {sapling_py-4.0.2 → sapling_py-4.1.0}/setup.py +11 -2
- sapling_py-4.1.0/test/test_client.py +158 -0
- sapling_py-4.0.2/PKG-INFO +0 -94
- sapling_py-4.0.2/README.md +0 -80
- sapling_py-4.0.2/sapling/version.py +0 -1
- sapling_py-4.0.2/sapling_py.egg-info/PKG-INFO +0 -94
- sapling_py-4.0.2/sapling_py.egg-info/requires.txt +0 -1
- {sapling_py-4.0.2 → sapling_py-4.1.0}/LICENSE +0 -0
- {sapling_py-4.0.2 → sapling_py-4.1.0}/sapling_py.egg-info/dependency_links.txt +0 -0
- {sapling_py-4.0.2 → sapling_py-4.1.0}/setup.cfg +0 -0
- {sapling_py-4.0.2 → sapling_py-4.1.0}/test/__init__.py +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sapling-py
|
|
3
|
+
Version: 4.1.0
|
|
4
|
+
Summary: Sapling Python Client
|
|
5
|
+
Home-page: https://sapling.ai
|
|
6
|
+
Author: Sapling Intelligence
|
|
7
|
+
Author-email: info@sapling.ai
|
|
8
|
+
License: Apache License 2.0
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Requires-Python: >=3.7
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: requests
|
|
17
|
+
Provides-Extra: test
|
|
18
|
+
Requires-Dist: pytest; extra == "test"
|
|
19
|
+
Requires-Dist: responses; extra == "test"
|
|
20
|
+
Dynamic: author
|
|
21
|
+
Dynamic: author-email
|
|
22
|
+
Dynamic: classifier
|
|
23
|
+
Dynamic: description
|
|
24
|
+
Dynamic: description-content-type
|
|
25
|
+
Dynamic: home-page
|
|
26
|
+
Dynamic: license
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
Dynamic: provides-extra
|
|
29
|
+
Dynamic: requires-dist
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
Dynamic: summary
|
|
32
|
+
|
|
33
|
+
# Sapling Python Client
|
|
34
|
+
|
|
35
|
+
Python SDK wrapper for the [Sapling.ai API](https://sapling.ai/docs).
|
|
36
|
+
|
|
37
|
+
Try our [grammar check demo](https://sapling.ai/grammar-check).
|
|
38
|
+
Compare against leading grammar checking tools and APIs like Grammarly (Grammerly), LanguageTool, ProWritingAid and Ginger.
|
|
39
|
+
|
|
40
|
+
## Overview
|
|
41
|
+
|
|
42
|
+
Sapling is a toolkit for helping developers build language model-powered applications.
|
|
43
|
+
The API provides spelling and grammar checking, autocomplete, tone detection, rephrasing, AI detection, and more.
|
|
44
|
+
|
|
45
|
+
Key Features:
|
|
46
|
+
- **60% More Corrections**: Outperforms [competing solutions](https://sapling.ai/comparison/api#sapling) at similar accuracy levels using state-of-the-art generative AI models.
|
|
47
|
+
- **Real-Time Performance**: Experience the same low-latency corrections as Sapling's native integrations.
|
|
48
|
+
- **Comprehensive Error Detection**: Identifies over 20 error types including prepositions, noun forms, verb tense, with both high-level and fine-grained error information.
|
|
49
|
+
- **Domain-Specific Models**: Get corrections optimized for your content type, from academic writing, to doctors notes, to user-generated reviews.
|
|
50
|
+
- **Enterprise-Grade Security**: Features include no data retention policies, [self-hosted/on-premises](https://sapling.ai/onprem) deployment options, and enterprise-grade [security policies and procedures](https://sapling.ai/security).
|
|
51
|
+
- **Rich Text Editor Integration**: Supports TinyMCE, CKEditor, QuillJS, Trix, ProseMirror, WordPress, Draft.js, Froala, Lexical and more. For web-based editors, consider using our [JavaScript SDK](https://sapling.ai/docs/sdk/JavaScript/quickstart) for display UI components.
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
Install the `sapling-py` package with [pip](https://pip.pypa.io/en/stable/installation/)
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
python -m pip install sapling-py
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Documentation
|
|
62
|
+
Documentation for the client is available at [Read the Docs](https://sapling.readthedocs.io/) and
|
|
63
|
+
documentation for the HTTP API is available at [Sapling.ai](https://sapling.ai/docs).
|
|
64
|
+
|
|
65
|
+
## Quickstart
|
|
66
|
+
|
|
67
|
+
- Register for an account at [Sapling.ai](https://sapling.ai).
|
|
68
|
+
- After registering and signing in, generate a development API key in your [dashboard](https://sapling.ai/user_settings).
|
|
69
|
+
- Install the Python client by following the installation steps above.
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from sapling import SaplingClient
|
|
73
|
+
|
|
74
|
+
API_KEY = '<YOUR_API_KEY>'
|
|
75
|
+
client = SaplingClient(api_key=API_KEY)
|
|
76
|
+
edits = client.edits('Lets get started!', session_id='test_session')
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The result should be an array of edits of this form:
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
[{
|
|
83
|
+
"id": "aa5ee291-a073-5146-8ebc-c9c899d01278",
|
|
84
|
+
"sentence": "Lets get started!",
|
|
85
|
+
"sentence_start": 0,
|
|
86
|
+
"start": 0,
|
|
87
|
+
"end": 4,
|
|
88
|
+
"replacement": "Let's",
|
|
89
|
+
"error_type": "R:OTHER",
|
|
90
|
+
"general_error_type": "Other",
|
|
91
|
+
}]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Get a production key by following [this documentation](https://sapling.ai/docs/api/api-access).
|
|
95
|
+
|
|
96
|
+
Here's some more information on [request options and response structure](https://sapling.ai/docs/api/edits-overview).
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
Copyright 2024--present Sapling Intelligence, Inc.
|
|
101
|
+
|
|
102
|
+
Licensed under the Apache License, Version 2.0.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Sapling Python Client
|
|
2
|
+
|
|
3
|
+
Python SDK wrapper for the [Sapling.ai API](https://sapling.ai/docs).
|
|
4
|
+
|
|
5
|
+
Try our [grammar check demo](https://sapling.ai/grammar-check).
|
|
6
|
+
Compare against leading grammar checking tools and APIs like Grammarly (Grammerly), LanguageTool, ProWritingAid and Ginger.
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Sapling is a toolkit for helping developers build language model-powered applications.
|
|
11
|
+
The API provides spelling and grammar checking, autocomplete, tone detection, rephrasing, AI detection, and more.
|
|
12
|
+
|
|
13
|
+
Key Features:
|
|
14
|
+
- **60% More Corrections**: Outperforms [competing solutions](https://sapling.ai/comparison/api#sapling) at similar accuracy levels using state-of-the-art generative AI models.
|
|
15
|
+
- **Real-Time Performance**: Experience the same low-latency corrections as Sapling's native integrations.
|
|
16
|
+
- **Comprehensive Error Detection**: Identifies over 20 error types including prepositions, noun forms, verb tense, with both high-level and fine-grained error information.
|
|
17
|
+
- **Domain-Specific Models**: Get corrections optimized for your content type, from academic writing, to doctors notes, to user-generated reviews.
|
|
18
|
+
- **Enterprise-Grade Security**: Features include no data retention policies, [self-hosted/on-premises](https://sapling.ai/onprem) deployment options, and enterprise-grade [security policies and procedures](https://sapling.ai/security).
|
|
19
|
+
- **Rich Text Editor Integration**: Supports TinyMCE, CKEditor, QuillJS, Trix, ProseMirror, WordPress, Draft.js, Froala, Lexical and more. For web-based editors, consider using our [JavaScript SDK](https://sapling.ai/docs/sdk/JavaScript/quickstart) for display UI components.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
Install the `sapling-py` package with [pip](https://pip.pypa.io/en/stable/installation/)
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
python -m pip install sapling-py
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Documentation
|
|
30
|
+
Documentation for the client is available at [Read the Docs](https://sapling.readthedocs.io/) and
|
|
31
|
+
documentation for the HTTP API is available at [Sapling.ai](https://sapling.ai/docs).
|
|
32
|
+
|
|
33
|
+
## Quickstart
|
|
34
|
+
|
|
35
|
+
- Register for an account at [Sapling.ai](https://sapling.ai).
|
|
36
|
+
- After registering and signing in, generate a development API key in your [dashboard](https://sapling.ai/user_settings).
|
|
37
|
+
- Install the Python client by following the installation steps above.
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from sapling import SaplingClient
|
|
41
|
+
|
|
42
|
+
API_KEY = '<YOUR_API_KEY>'
|
|
43
|
+
client = SaplingClient(api_key=API_KEY)
|
|
44
|
+
edits = client.edits('Lets get started!', session_id='test_session')
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The result should be an array of edits of this form:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
[{
|
|
51
|
+
"id": "aa5ee291-a073-5146-8ebc-c9c899d01278",
|
|
52
|
+
"sentence": "Lets get started!",
|
|
53
|
+
"sentence_start": 0,
|
|
54
|
+
"start": 0,
|
|
55
|
+
"end": 4,
|
|
56
|
+
"replacement": "Let's",
|
|
57
|
+
"error_type": "R:OTHER",
|
|
58
|
+
"general_error_type": "Other",
|
|
59
|
+
}]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Get a production key by following [this documentation](https://sapling.ai/docs/api/api-access).
|
|
63
|
+
|
|
64
|
+
Here's some more information on [request options and response structure](https://sapling.ai/docs/api/edits-overview).
|
|
65
|
+
|
|
66
|
+
## License
|
|
67
|
+
|
|
68
|
+
Copyright 2024--present Sapling Intelligence, Inc.
|
|
69
|
+
|
|
70
|
+
Licensed under the Apache License, Version 2.0.
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import requests
|
|
2
2
|
import uuid
|
|
3
3
|
|
|
4
|
+
|
|
5
|
+
class SaplingError(Exception):
|
|
6
|
+
'''
|
|
7
|
+
Raised when the Sapling API returns a non-2xx response.
|
|
8
|
+
|
|
9
|
+
:ivar status_code: HTTP status code returned by the API.
|
|
10
|
+
:ivar body: Raw response body returned by the API (may be empty).
|
|
11
|
+
'''
|
|
12
|
+
|
|
13
|
+
def __init__(self, status_code, body=None):
|
|
14
|
+
self.status_code = status_code
|
|
15
|
+
self.body = body
|
|
16
|
+
super().__init__(f'HTTP {status_code}: {body}')
|
|
17
|
+
|
|
18
|
+
|
|
4
19
|
class SaplingClient:
|
|
5
20
|
'''
|
|
6
21
|
Sapling client class. Provides a mapping of Python functions to Sapling HTTP REST APIs.
|
|
@@ -28,6 +43,32 @@ class SaplingClient:
|
|
|
28
43
|
self.pathname = pathname or '/api/v1/'
|
|
29
44
|
self.url_endpoint = self.hostname + self.pathname
|
|
30
45
|
self.default_session_id = str(uuid.uuid4())
|
|
46
|
+
self.session = requests.Session()
|
|
47
|
+
|
|
48
|
+
def _request(self, url, data):
|
|
49
|
+
'''
|
|
50
|
+
Issues a POST request to the Sapling API and returns the parsed JSON body.
|
|
51
|
+
|
|
52
|
+
:param url: Fully-qualified endpoint URL.
|
|
53
|
+
:type url: str
|
|
54
|
+
:param data: JSON-serializable request body.
|
|
55
|
+
:type data: dict
|
|
56
|
+
:rtype: dict, list, or None
|
|
57
|
+
:raises SaplingError: If the API responds with a non-2xx status code.
|
|
58
|
+
'''
|
|
59
|
+
resp = self.session.post(
|
|
60
|
+
url,
|
|
61
|
+
json=data,
|
|
62
|
+
timeout=self.timeout,
|
|
63
|
+
)
|
|
64
|
+
if not 200 <= resp.status_code < 300:
|
|
65
|
+
raise SaplingError(resp.status_code, resp.text)
|
|
66
|
+
if not resp.content:
|
|
67
|
+
return None
|
|
68
|
+
try:
|
|
69
|
+
return resp.json()
|
|
70
|
+
except ValueError:
|
|
71
|
+
return None
|
|
31
72
|
|
|
32
73
|
def edits(
|
|
33
74
|
self,
|
|
@@ -140,14 +181,7 @@ class SaplingClient:
|
|
|
140
181
|
if is_anon_user is not None:
|
|
141
182
|
data['is_anon_user'] = is_anon_user
|
|
142
183
|
|
|
143
|
-
|
|
144
|
-
url,
|
|
145
|
-
json=data,
|
|
146
|
-
timeout=self.timeout,
|
|
147
|
-
)
|
|
148
|
-
if 200 <= resp.status_code < 300:
|
|
149
|
-
return resp.json()
|
|
150
|
-
raise Exception(f'HTTP {resp.status_code}: {resp.text}')
|
|
184
|
+
return self._request(url, data)
|
|
151
185
|
|
|
152
186
|
def accept_edit(
|
|
153
187
|
self,
|
|
@@ -179,14 +213,7 @@ class SaplingClient:
|
|
|
179
213
|
if user_id is not None:
|
|
180
214
|
data['user_id'] = user_id
|
|
181
215
|
|
|
182
|
-
|
|
183
|
-
url,
|
|
184
|
-
json=data,
|
|
185
|
-
timeout=self.timeout,
|
|
186
|
-
)
|
|
187
|
-
if 200 <= resp.status_code < 300:
|
|
188
|
-
return
|
|
189
|
-
raise Exception(f'HTTP {resp.status_code}: resp.text')
|
|
216
|
+
self._request(url, data)
|
|
190
217
|
|
|
191
218
|
def reject_edit(
|
|
192
219
|
self,
|
|
@@ -218,14 +245,7 @@ class SaplingClient:
|
|
|
218
245
|
if user_id is not None:
|
|
219
246
|
data['user_id'] = user_id
|
|
220
247
|
|
|
221
|
-
|
|
222
|
-
url,
|
|
223
|
-
json=data,
|
|
224
|
-
timeout=self.timeout,
|
|
225
|
-
)
|
|
226
|
-
if 200 <= resp.status_code < 300:
|
|
227
|
-
return
|
|
228
|
-
raise Exception(f'HTTP {resp.status_code}: resp.text')
|
|
248
|
+
self._request(url, data)
|
|
229
249
|
|
|
230
250
|
def spellcheck(
|
|
231
251
|
self,
|
|
@@ -255,8 +275,8 @@ class SaplingClient:
|
|
|
255
275
|
:type lang: str
|
|
256
276
|
:param auto_apply: Whether to return a field with edits applied to the text. Cannot be set with multiple_edits option.
|
|
257
277
|
:type auto_apply: bool
|
|
258
|
-
:param
|
|
259
|
-
:type
|
|
278
|
+
:param user_data: Optional custom data (e.g. a personal dictionary) to inform spellchecking.
|
|
279
|
+
:type user_data: dict
|
|
260
280
|
:param variety: Specifies regional English variety preference. Defaults to the configuration in the user Sapling dashboard.
|
|
261
281
|
:type variety: str
|
|
262
282
|
:param user_id: Track IDs representing your end users
|
|
@@ -343,14 +363,7 @@ class SaplingClient:
|
|
|
343
363
|
if is_anon_user is not None:
|
|
344
364
|
data['is_anon_user'] = is_anon_user
|
|
345
365
|
|
|
346
|
-
|
|
347
|
-
url,
|
|
348
|
-
json=data,
|
|
349
|
-
timeout=self.timeout,
|
|
350
|
-
)
|
|
351
|
-
if 200 <= resp.status_code < 300:
|
|
352
|
-
return resp.json()
|
|
353
|
-
raise Exception(f'HTTP {resp.status_code}: {resp.text}')
|
|
366
|
+
return self._request(url, data)
|
|
354
367
|
|
|
355
368
|
|
|
356
369
|
def complete(
|
|
@@ -374,14 +387,7 @@ class SaplingClient:
|
|
|
374
387
|
'session_id': session_id,
|
|
375
388
|
}
|
|
376
389
|
|
|
377
|
-
|
|
378
|
-
url,
|
|
379
|
-
json=data,
|
|
380
|
-
timeout=self.timeout,
|
|
381
|
-
)
|
|
382
|
-
if 200 <= resp.status_code < 300:
|
|
383
|
-
return resp.json()
|
|
384
|
-
raise Exception(f'HTTP {resp.status_code}: {resp.text}')
|
|
390
|
+
return self._request(url, data)
|
|
385
391
|
|
|
386
392
|
def accept_complete(
|
|
387
393
|
self,
|
|
@@ -404,7 +410,7 @@ class SaplingClient:
|
|
|
404
410
|
:type completion: str
|
|
405
411
|
'''
|
|
406
412
|
url = f'{self.url_endpoint}complete/{complete_uuid}/accept'
|
|
407
|
-
session_id = session_id or
|
|
413
|
+
session_id = session_id or self.default_session_id
|
|
408
414
|
data = {
|
|
409
415
|
'key': self.api_key,
|
|
410
416
|
'session_id': session_id,
|
|
@@ -413,14 +419,7 @@ class SaplingClient:
|
|
|
413
419
|
'completion': completion,
|
|
414
420
|
}
|
|
415
421
|
}
|
|
416
|
-
|
|
417
|
-
url,
|
|
418
|
-
json=data,
|
|
419
|
-
timeout=self.timeout,
|
|
420
|
-
)
|
|
421
|
-
if 200 <= resp.status_code < 300:
|
|
422
|
-
return
|
|
423
|
-
raise Exception(f'HTTP {resp.status_code}: resp.text')
|
|
422
|
+
self._request(url, data)
|
|
424
423
|
|
|
425
424
|
def aidetect(
|
|
426
425
|
self,
|
|
@@ -430,7 +429,7 @@ class SaplingClient:
|
|
|
430
429
|
'''
|
|
431
430
|
Score a piece of text on how likely it was generated by AI.
|
|
432
431
|
|
|
433
|
-
:param text: Text to
|
|
432
|
+
:param text: Text to score for AI-generated content.
|
|
434
433
|
:type text: str
|
|
435
434
|
:param sent_scores: If true, each sentence will also be scored individually.
|
|
436
435
|
:type sent_scores: bool
|
|
@@ -449,14 +448,7 @@ class SaplingClient:
|
|
|
449
448
|
}
|
|
450
449
|
if sent_scores is not None:
|
|
451
450
|
data['sent_scores'] = sent_scores
|
|
452
|
-
|
|
453
|
-
url,
|
|
454
|
-
json=data,
|
|
455
|
-
timeout=self.timeout,
|
|
456
|
-
)
|
|
457
|
-
if 200 <= resp.status_code < 300:
|
|
458
|
-
return resp.json()
|
|
459
|
-
raise Exception(f'HTTP {resp.status_code}: resp.text')
|
|
451
|
+
return self._request(url, data)
|
|
460
452
|
|
|
461
453
|
def chunk_text(
|
|
462
454
|
self,
|
|
@@ -487,14 +479,7 @@ class SaplingClient:
|
|
|
487
479
|
}
|
|
488
480
|
if step_size is not None:
|
|
489
481
|
data['step_size'] = step_size
|
|
490
|
-
|
|
491
|
-
url,
|
|
492
|
-
json=data,
|
|
493
|
-
timeout=self.timeout,
|
|
494
|
-
)
|
|
495
|
-
if 200 <= resp.status_code < 300:
|
|
496
|
-
return resp.json()
|
|
497
|
-
raise Exception(f'HTTP {resp.status_code}: {resp.text}')
|
|
482
|
+
return self._request(url, data)
|
|
498
483
|
|
|
499
484
|
def chunk_html(
|
|
500
485
|
self,
|
|
@@ -527,14 +512,7 @@ class SaplingClient:
|
|
|
527
512
|
}
|
|
528
513
|
if step_size is not None:
|
|
529
514
|
data['step_size'] = step_size
|
|
530
|
-
|
|
531
|
-
url,
|
|
532
|
-
json=data,
|
|
533
|
-
timeout=self.timeout,
|
|
534
|
-
)
|
|
535
|
-
if 200 <= resp.status_code < 300:
|
|
536
|
-
return resp.json()
|
|
537
|
-
raise Exception(f'HTTP {resp.status_code}: {resp.text}')
|
|
515
|
+
return self._request(url, data)
|
|
538
516
|
|
|
539
517
|
def postprocess(
|
|
540
518
|
self,
|
|
@@ -578,11 +556,188 @@ class SaplingClient:
|
|
|
578
556
|
'session_id': session_id,
|
|
579
557
|
'operations': operations,
|
|
580
558
|
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
559
|
+
return self._request(url, data)
|
|
560
|
+
|
|
561
|
+
def rephrase(
|
|
562
|
+
self,
|
|
563
|
+
text,
|
|
564
|
+
mapping=None,
|
|
565
|
+
tone_mapping=None,
|
|
566
|
+
tense_mapping=None,
|
|
567
|
+
num_results=None,
|
|
568
|
+
session_id=None,
|
|
569
|
+
):
|
|
570
|
+
'''
|
|
571
|
+
Rephrases the input text, optionally applying a style transformation.
|
|
572
|
+
|
|
573
|
+
Given an input sentence, returns output sentences that preserve meaning
|
|
574
|
+
but use alternative phrasings or styles.
|
|
575
|
+
|
|
576
|
+
:param text: Text to rephrase. Current maximum length is 400 characters.
|
|
577
|
+
:type text: str
|
|
578
|
+
:param mapping: The transformation to apply. Defaults to `paraphrase`.
|
|
579
|
+
Options include: `paraphrase`, `informal_to_formal`, `passive_to_active`,
|
|
580
|
+
`active_to_passive`, `sentence_split`, `expand`, and `switch_tone`.
|
|
581
|
+
:type mapping: str
|
|
582
|
+
:param tone_mapping: Target tone when `mapping` is `switch_tone`. Options
|
|
583
|
+
include: `straightforward`, `confident`, `friendly`, and `empathetic`.
|
|
584
|
+
:type tone_mapping: str
|
|
585
|
+
:param tense_mapping: Target tense transformation, when applicable.
|
|
586
|
+
:type tense_mapping: str
|
|
587
|
+
:param num_results: Number of results to return (currently only for
|
|
588
|
+
`paraphrase`). Minimum 1, maximum 8. Defaults to 5.
|
|
589
|
+
:type num_results: int
|
|
590
|
+
:param session_id: Unique name or UUID of document or portion of text that is being processed
|
|
591
|
+
:type session_id: str
|
|
592
|
+
:rtype: dict
|
|
593
|
+
:return:
|
|
594
|
+
- results: List of rephrases, each with `original`, `replacement`,
|
|
595
|
+
`rephrase_type`, `model_version`, and `hash`.
|
|
596
|
+
'''
|
|
597
|
+
url = self.url_endpoint + 'rephrase'
|
|
598
|
+
session_id = session_id or self.default_session_id
|
|
599
|
+
data = {
|
|
600
|
+
'key': self.api_key,
|
|
601
|
+
'text': text,
|
|
602
|
+
'session_id': session_id,
|
|
603
|
+
}
|
|
604
|
+
if mapping is not None:
|
|
605
|
+
data['mapping'] = mapping
|
|
606
|
+
if tone_mapping is not None:
|
|
607
|
+
data['tone_mapping'] = tone_mapping
|
|
608
|
+
if tense_mapping is not None:
|
|
609
|
+
data['tense_mapping'] = tense_mapping
|
|
610
|
+
if num_results is not None:
|
|
611
|
+
data['num_results'] = num_results
|
|
612
|
+
return self._request(url, data)
|
|
613
|
+
|
|
614
|
+
def summarize(
|
|
615
|
+
self,
|
|
616
|
+
text,
|
|
617
|
+
):
|
|
618
|
+
'''
|
|
619
|
+
Summarizes a longer document into a shorter, more digestible one.
|
|
620
|
+
|
|
621
|
+
:param text: Input document to summarize.
|
|
622
|
+
:type text: str
|
|
623
|
+
:rtype: dict
|
|
624
|
+
:return:
|
|
625
|
+
- result: The summarized text.
|
|
626
|
+
'''
|
|
627
|
+
url = self.url_endpoint + 'summarize'
|
|
628
|
+
data = {
|
|
629
|
+
'key': self.api_key,
|
|
630
|
+
'text': text,
|
|
631
|
+
}
|
|
632
|
+
return self._request(url, data)
|
|
633
|
+
|
|
634
|
+
def tone(
|
|
635
|
+
self,
|
|
636
|
+
text,
|
|
637
|
+
):
|
|
638
|
+
'''
|
|
639
|
+
Detects the tone of the provided text across 28 fine-grained categories.
|
|
640
|
+
|
|
641
|
+
The overall tone is returned along with the tone for each sentence.
|
|
642
|
+
|
|
643
|
+
:param text: Text to analyze the tone for.
|
|
644
|
+
:type text: str
|
|
645
|
+
:rtype: dict
|
|
646
|
+
:return:
|
|
647
|
+
- sents: The sentences the text contains.
|
|
648
|
+
- overall: List of ``(probability, tone, emoji)`` tuples for the whole text.
|
|
649
|
+
- results: For each sentence, a list of ``(probability, tone, emoji)`` tuples.
|
|
650
|
+
'''
|
|
651
|
+
url = self.url_endpoint + 'tone'
|
|
652
|
+
data = {
|
|
653
|
+
'key': self.api_key,
|
|
654
|
+
'text': text,
|
|
655
|
+
}
|
|
656
|
+
return self._request(url, data)
|
|
657
|
+
|
|
658
|
+
def sentiment(
|
|
659
|
+
self,
|
|
660
|
+
text,
|
|
661
|
+
):
|
|
662
|
+
'''
|
|
663
|
+
Detects the sentiment (positive, negative, or neutral) of the provided text.
|
|
664
|
+
|
|
665
|
+
The overall sentiment is returned along with the sentiment for each sentence.
|
|
666
|
+
|
|
667
|
+
:param text: Text to analyze the sentiment for.
|
|
668
|
+
:type text: str
|
|
669
|
+
:rtype: dict
|
|
670
|
+
:return:
|
|
671
|
+
- sents: The sentences the text contains.
|
|
672
|
+
- overall: List of ``(probability, sentiment)`` tuples for the whole text.
|
|
673
|
+
- results: For each sentence, a list of ``(probability, sentiment)`` tuples.
|
|
674
|
+
'''
|
|
675
|
+
url = self.url_endpoint + 'sentiment'
|
|
676
|
+
data = {
|
|
677
|
+
'key': self.api_key,
|
|
678
|
+
'text': text,
|
|
679
|
+
}
|
|
680
|
+
return self._request(url, data)
|
|
681
|
+
|
|
682
|
+
def quality(
|
|
683
|
+
self,
|
|
684
|
+
text,
|
|
685
|
+
):
|
|
686
|
+
'''
|
|
687
|
+
Computes a quality score for the provided text based on how "surprising"
|
|
688
|
+
the text is to the model. Lower surprisal corresponds to higher scores.
|
|
689
|
+
|
|
690
|
+
:param text: Text to compute a quality score for.
|
|
691
|
+
:type text: str
|
|
692
|
+
:rtype: dict
|
|
693
|
+
:return:
|
|
694
|
+
- score: A score from 1 (low quality) to 5 (high quality).
|
|
695
|
+
'''
|
|
696
|
+
url = self.url_endpoint + 'quality'
|
|
697
|
+
data = {
|
|
698
|
+
'key': self.api_key,
|
|
699
|
+
'text': text,
|
|
700
|
+
}
|
|
701
|
+
return self._request(url, data)
|
|
702
|
+
|
|
703
|
+
def langdetect(
|
|
704
|
+
self,
|
|
705
|
+
text,
|
|
706
|
+
):
|
|
707
|
+
'''
|
|
708
|
+
Identifies the language of the provided text.
|
|
709
|
+
|
|
710
|
+
:param text: Text to identify the language for.
|
|
711
|
+
:type text: str
|
|
712
|
+
:rtype: dict
|
|
713
|
+
:return:
|
|
714
|
+
- lang: The detected language code.
|
|
715
|
+
- conf: Confidence score for the detection result.
|
|
716
|
+
'''
|
|
717
|
+
url = self.url_endpoint + 'langdetect'
|
|
718
|
+
data = {
|
|
719
|
+
'key': self.api_key,
|
|
720
|
+
'text': text,
|
|
721
|
+
}
|
|
722
|
+
return self._request(url, data)
|
|
723
|
+
|
|
724
|
+
def profanity(
|
|
725
|
+
self,
|
|
726
|
+
text,
|
|
727
|
+
):
|
|
728
|
+
'''
|
|
729
|
+
Checks the provided text for profanity, returning a 0/1 label per token.
|
|
730
|
+
|
|
731
|
+
:param text: Text to check for profanity.
|
|
732
|
+
:type text: str
|
|
733
|
+
:rtype: dict
|
|
734
|
+
:return:
|
|
735
|
+
- toks: The tokens (words) detected in the text.
|
|
736
|
+
- labels: For each token, 0 (not profanity) or 1 (profanity).
|
|
737
|
+
'''
|
|
738
|
+
url = self.url_endpoint + 'profanity'
|
|
739
|
+
data = {
|
|
740
|
+
'key': self.api_key,
|
|
741
|
+
'text': text,
|
|
742
|
+
}
|
|
743
|
+
return self._request(url, data)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '4.1.0'
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sapling-py
|
|
3
|
+
Version: 4.1.0
|
|
4
|
+
Summary: Sapling Python Client
|
|
5
|
+
Home-page: https://sapling.ai
|
|
6
|
+
Author: Sapling Intelligence
|
|
7
|
+
Author-email: info@sapling.ai
|
|
8
|
+
License: Apache License 2.0
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Requires-Python: >=3.7
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: requests
|
|
17
|
+
Provides-Extra: test
|
|
18
|
+
Requires-Dist: pytest; extra == "test"
|
|
19
|
+
Requires-Dist: responses; extra == "test"
|
|
20
|
+
Dynamic: author
|
|
21
|
+
Dynamic: author-email
|
|
22
|
+
Dynamic: classifier
|
|
23
|
+
Dynamic: description
|
|
24
|
+
Dynamic: description-content-type
|
|
25
|
+
Dynamic: home-page
|
|
26
|
+
Dynamic: license
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
Dynamic: provides-extra
|
|
29
|
+
Dynamic: requires-dist
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
Dynamic: summary
|
|
32
|
+
|
|
33
|
+
# Sapling Python Client
|
|
34
|
+
|
|
35
|
+
Python SDK wrapper for the [Sapling.ai API](https://sapling.ai/docs).
|
|
36
|
+
|
|
37
|
+
Try our [grammar check demo](https://sapling.ai/grammar-check).
|
|
38
|
+
Compare against leading grammar checking tools and APIs like Grammarly (Grammerly), LanguageTool, ProWritingAid and Ginger.
|
|
39
|
+
|
|
40
|
+
## Overview
|
|
41
|
+
|
|
42
|
+
Sapling is a toolkit for helping developers build language model-powered applications.
|
|
43
|
+
The API provides spelling and grammar checking, autocomplete, tone detection, rephrasing, AI detection, and more.
|
|
44
|
+
|
|
45
|
+
Key Features:
|
|
46
|
+
- **60% More Corrections**: Outperforms [competing solutions](https://sapling.ai/comparison/api#sapling) at similar accuracy levels using state-of-the-art generative AI models.
|
|
47
|
+
- **Real-Time Performance**: Experience the same low-latency corrections as Sapling's native integrations.
|
|
48
|
+
- **Comprehensive Error Detection**: Identifies over 20 error types including prepositions, noun forms, verb tense, with both high-level and fine-grained error information.
|
|
49
|
+
- **Domain-Specific Models**: Get corrections optimized for your content type, from academic writing, to doctors notes, to user-generated reviews.
|
|
50
|
+
- **Enterprise-Grade Security**: Features include no data retention policies, [self-hosted/on-premises](https://sapling.ai/onprem) deployment options, and enterprise-grade [security policies and procedures](https://sapling.ai/security).
|
|
51
|
+
- **Rich Text Editor Integration**: Supports TinyMCE, CKEditor, QuillJS, Trix, ProseMirror, WordPress, Draft.js, Froala, Lexical and more. For web-based editors, consider using our [JavaScript SDK](https://sapling.ai/docs/sdk/JavaScript/quickstart) for display UI components.
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
Install the `sapling-py` package with [pip](https://pip.pypa.io/en/stable/installation/)
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
python -m pip install sapling-py
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Documentation
|
|
62
|
+
Documentation for the client is available at [Read the Docs](https://sapling.readthedocs.io/) and
|
|
63
|
+
documentation for the HTTP API is available at [Sapling.ai](https://sapling.ai/docs).
|
|
64
|
+
|
|
65
|
+
## Quickstart
|
|
66
|
+
|
|
67
|
+
- Register for an account at [Sapling.ai](https://sapling.ai).
|
|
68
|
+
- After registering and signing in, generate a development API key in your [dashboard](https://sapling.ai/user_settings).
|
|
69
|
+
- Install the Python client by following the installation steps above.
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from sapling import SaplingClient
|
|
73
|
+
|
|
74
|
+
API_KEY = '<YOUR_API_KEY>'
|
|
75
|
+
client = SaplingClient(api_key=API_KEY)
|
|
76
|
+
edits = client.edits('Lets get started!', session_id='test_session')
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The result should be an array of edits of this form:
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
[{
|
|
83
|
+
"id": "aa5ee291-a073-5146-8ebc-c9c899d01278",
|
|
84
|
+
"sentence": "Lets get started!",
|
|
85
|
+
"sentence_start": 0,
|
|
86
|
+
"start": 0,
|
|
87
|
+
"end": 4,
|
|
88
|
+
"replacement": "Let's",
|
|
89
|
+
"error_type": "R:OTHER",
|
|
90
|
+
"general_error_type": "Other",
|
|
91
|
+
}]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Get a production key by following [this documentation](https://sapling.ai/docs/api/api-access).
|
|
95
|
+
|
|
96
|
+
Here's some more information on [request options and response structure](https://sapling.ai/docs/api/edits-overview).
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
Copyright 2024--present Sapling Intelligence, Inc.
|
|
101
|
+
|
|
102
|
+
Licensed under the Apache License, Version 2.0.
|
|
@@ -20,13 +20,22 @@ setup(
|
|
|
20
20
|
author_email='info@sapling.ai',
|
|
21
21
|
license='Apache License 2.0',
|
|
22
22
|
classifiers=[
|
|
23
|
-
'Development Status ::
|
|
23
|
+
'Development Status :: 5 - Production/Stable',
|
|
24
|
+
'License :: OSI Approved :: Apache Software License',
|
|
24
25
|
'Programming Language :: Python :: 3',
|
|
26
|
+
'Programming Language :: Python :: 3 :: Only',
|
|
25
27
|
],
|
|
26
|
-
packages=find_packages(),
|
|
28
|
+
packages=find_packages(exclude=['test', 'test.*']),
|
|
27
29
|
package_data={'':[]},
|
|
28
30
|
include_package_data=True,
|
|
31
|
+
python_requires='>=3.7',
|
|
29
32
|
install_requires=[
|
|
30
33
|
'requests'
|
|
31
34
|
],
|
|
35
|
+
extras_require={
|
|
36
|
+
'test': [
|
|
37
|
+
'pytest',
|
|
38
|
+
'responses',
|
|
39
|
+
],
|
|
40
|
+
},
|
|
32
41
|
)
|
|
@@ -0,0 +1,158 @@
|
|
|
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
|
+
|
|
12
|
+
@pytest.fixture
|
|
13
|
+
def client():
|
|
14
|
+
return SaplingClient(api_key=API_KEY)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _last_request_body():
|
|
18
|
+
'''Return the JSON body of the most recent mocked request.'''
|
|
19
|
+
return json.loads(responses.calls[-1].request.body)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@responses.activate
|
|
23
|
+
def test_edits_returns_json_and_sends_key(client):
|
|
24
|
+
responses.add(
|
|
25
|
+
responses.POST,
|
|
26
|
+
BASE + 'edits',
|
|
27
|
+
json={'edits': [{'replacement': "Let's"}]},
|
|
28
|
+
status=200,
|
|
29
|
+
)
|
|
30
|
+
result = client.edits('Lets go', session_id='s1')
|
|
31
|
+
assert result == {'edits': [{'replacement': "Let's"}]}
|
|
32
|
+
body = _last_request_body()
|
|
33
|
+
assert body['key'] == API_KEY
|
|
34
|
+
assert body['text'] == 'Lets go'
|
|
35
|
+
assert body['session_id'] == 's1'
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@responses.activate
|
|
39
|
+
def test_edits_uses_default_session_id(client):
|
|
40
|
+
responses.add(responses.POST, BASE + 'edits', json={'edits': []}, status=200)
|
|
41
|
+
client.edits('hi')
|
|
42
|
+
assert _last_request_body()['session_id'] == client.default_session_id
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@responses.activate
|
|
46
|
+
def test_optional_params_only_sent_when_provided(client):
|
|
47
|
+
responses.add(responses.POST, BASE + 'edits', json={'edits': []}, status=200)
|
|
48
|
+
client.edits('hi')
|
|
49
|
+
body = _last_request_body()
|
|
50
|
+
for absent in ('lang', 'variety', 'medical', 'advanced_edits', 'user_id', 'is_anon_user'):
|
|
51
|
+
assert absent not in body
|
|
52
|
+
# auto_apply defaults to False and is always included
|
|
53
|
+
assert body['auto_apply'] is False
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@responses.activate
|
|
57
|
+
def test_error_response_raises_saplingerror_with_body(client):
|
|
58
|
+
responses.add(
|
|
59
|
+
responses.POST,
|
|
60
|
+
BASE + 'edits',
|
|
61
|
+
json={'msg': 'Invalid text.'},
|
|
62
|
+
status=400,
|
|
63
|
+
)
|
|
64
|
+
with pytest.raises(SaplingError) as exc_info:
|
|
65
|
+
client.edits('hi')
|
|
66
|
+
err = exc_info.value
|
|
67
|
+
assert err.status_code == 400
|
|
68
|
+
# Regression test: the response body must be interpolated into the message.
|
|
69
|
+
assert 'Invalid text.' in str(err)
|
|
70
|
+
assert 'Invalid text.' in err.body
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@responses.activate
|
|
74
|
+
def test_accept_edit_error_includes_body(client):
|
|
75
|
+
'''Regression: accept_edit previously never interpolated resp.text.'''
|
|
76
|
+
responses.add(
|
|
77
|
+
responses.POST,
|
|
78
|
+
BASE + 'edits/some-uuid/accept',
|
|
79
|
+
json={'msg': 'Not found'},
|
|
80
|
+
status=404,
|
|
81
|
+
)
|
|
82
|
+
with pytest.raises(SaplingError) as exc_info:
|
|
83
|
+
client.accept_edit('some-uuid', session_id='s1')
|
|
84
|
+
assert 'Not found' in str(exc_info.value)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@responses.activate
|
|
88
|
+
def test_accept_edit_success_returns_none(client):
|
|
89
|
+
responses.add(responses.POST, BASE + 'edits/some-uuid/accept', body='', status=200)
|
|
90
|
+
assert client.accept_edit('some-uuid') is None
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@responses.activate
|
|
94
|
+
def test_reject_edit_success_returns_none(client):
|
|
95
|
+
responses.add(responses.POST, BASE + 'edits/some-uuid/reject', body='', status=200)
|
|
96
|
+
assert client.reject_edit('some-uuid') is None
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@responses.activate
|
|
100
|
+
def test_accept_complete_sends_string_session_id(client):
|
|
101
|
+
'''Regression: session_id fallback must be a str, not a uuid.UUID.'''
|
|
102
|
+
responses.add(responses.POST, BASE + 'complete/c-uuid/accept', body='', status=200)
|
|
103
|
+
client.accept_complete('c-uuid', 'the query', 'the completion')
|
|
104
|
+
body = _last_request_body()
|
|
105
|
+
assert isinstance(body['session_id'], str)
|
|
106
|
+
assert body['session_id'] == client.default_session_id
|
|
107
|
+
assert body['context'] == {'query': 'the query', 'completion': 'the completion'}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@responses.activate
|
|
111
|
+
def test_aidetect_error_includes_body(client):
|
|
112
|
+
'''Regression: aidetect previously never interpolated resp.text.'''
|
|
113
|
+
responses.add(responses.POST, BASE + 'aidetect', json={'msg': 'boom'}, status=500)
|
|
114
|
+
with pytest.raises(SaplingError) as exc_info:
|
|
115
|
+
client.aidetect('some text')
|
|
116
|
+
assert 'boom' in str(exc_info.value)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@responses.activate
|
|
120
|
+
def test_rephrase_sends_expected_params(client):
|
|
121
|
+
responses.add(responses.POST, BASE + 'rephrase', json={'results': []}, status=200)
|
|
122
|
+
client.rephrase('hey wuts up', mapping='informal_to_formal', num_results=3)
|
|
123
|
+
body = _last_request_body()
|
|
124
|
+
assert body['text'] == 'hey wuts up'
|
|
125
|
+
assert body['mapping'] == 'informal_to_formal'
|
|
126
|
+
assert body['num_results'] == 3
|
|
127
|
+
assert 'session_id' in body
|
|
128
|
+
# Unset optional params should be omitted.
|
|
129
|
+
assert 'tone_mapping' not in body
|
|
130
|
+
assert 'tense_mapping' not in body
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@pytest.mark.parametrize(
|
|
134
|
+
'method,path,payload',
|
|
135
|
+
[
|
|
136
|
+
('summarize', 'summarize', {'result': 'short'}),
|
|
137
|
+
('tone', 'tone', {'overall': [], 'results': [], 'sents': []}),
|
|
138
|
+
('sentiment', 'sentiment', {'overall': [], 'results': [], 'sents': []}),
|
|
139
|
+
('quality', 'quality', {'score': 3.5}),
|
|
140
|
+
('langdetect', 'langdetect', {'lang': 'en', 'conf': 0.99}),
|
|
141
|
+
('profanity', 'profanity', {'toks': ['a'], 'labels': [0]}),
|
|
142
|
+
],
|
|
143
|
+
)
|
|
144
|
+
@responses.activate
|
|
145
|
+
def test_single_text_endpoints(client, method, path, payload):
|
|
146
|
+
responses.add(responses.POST, BASE + path, json=payload, status=200)
|
|
147
|
+
result = getattr(client, method)('some text')
|
|
148
|
+
assert result == payload
|
|
149
|
+
body = _last_request_body()
|
|
150
|
+
assert body == {'key': API_KEY, 'text': 'some text'}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@responses.activate
|
|
154
|
+
def test_hostname_and_pathname_override():
|
|
155
|
+
client = SaplingClient(api_key=API_KEY, hostname='http://localhost:5000', pathname='/api/v1/')
|
|
156
|
+
responses.add(responses.POST, 'http://localhost:5000/api/v1/edits', json={'edits': []}, status=200)
|
|
157
|
+
client.edits('hi')
|
|
158
|
+
assert responses.calls[-1].request.url == 'http://localhost:5000/api/v1/edits'
|
sapling_py-4.0.2/PKG-INFO
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: sapling-py
|
|
3
|
-
Version: 4.0.2
|
|
4
|
-
Summary: Sapling Python Client
|
|
5
|
-
Home-page: https://sapling.ai
|
|
6
|
-
Author: Sapling Intelligence
|
|
7
|
-
Author-email: info@sapling.ai
|
|
8
|
-
License: Apache License 2.0
|
|
9
|
-
Classifier: Development Status :: 3 - Alpha
|
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Description-Content-Type: text/markdown
|
|
12
|
-
License-File: LICENSE
|
|
13
|
-
Requires-Dist: requests
|
|
14
|
-
|
|
15
|
-
# Sapling Python Client
|
|
16
|
-
|
|
17
|
-
Python wrapper for the [Sapling.ai API](https://sapling.ai/api).
|
|
18
|
-
|
|
19
|
-
Try out a [grammar check demo](https://sapling.ai/grammar-check).
|
|
20
|
-
Compare against grammar checking tools and APIs like Grammarly (Grammerly), LanguageTool, ProWritingAid and Ginger.
|
|
21
|
-
|
|
22
|
-
Functionality
|
|
23
|
-
--------
|
|
24
|
-
|
|
25
|
-
Sapling is an AI messaging assistant.
|
|
26
|
-
The API currently offers spelling and grammar checking endpoints.
|
|
27
|
-
|
|
28
|
-
Benefits include:
|
|
29
|
-
- **60% more grammar corrections**: compared to [other systems](https://sapling.ai/comparison/api) at similar accuracy using state-of-the-art machine learning systems for natural language processing.
|
|
30
|
-
- **Low Latency**: Achieve the same real-time performance that users of Sapling's own interface experience.
|
|
31
|
-
- **Over 20 error types**: Error categories such as preposition, noun form, and verb tense, including both high-level and fine-grained error information.
|
|
32
|
-
- **Custom Models**: Get corrections and edits tuned to the domain of your text—for example academic writing vs. subtitles.
|
|
33
|
-
- **Enterprise Security**: Ask us about our no data retention policies, [self-hosted/on-premises](https://sapling.ai/onprem) deployment options, and other [cybersecurity policies and procedures](https://sapling.ai/security).
|
|
34
|
-
- **Rich Text Editor Support**: TinyMCE, CKEditor, QuillJS, Trix, ProseMirror, WordPress, Draft.js, Froala, Lexical and others. Consider using [Sapling's JavaScript SDK](https://sapling.ai/docs/sdk/JavaScript/quickstart) for displaying the API's outputs on webpage editors.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Installation
|
|
38
|
-
--------
|
|
39
|
-
|
|
40
|
-
Install the `sapling-py` package with [pip](https://pip.pypa.io/en/stable/installation/)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
python -m pip install sapling-py
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
Documentation
|
|
49
|
-
-------------
|
|
50
|
-
|
|
51
|
-
Documentation for the client is available at [Read the Docs](https://sapling.readthedocs.io/) and
|
|
52
|
-
documentation for the HTTP API is available at [Sapling.ai](https://sapling.ai/docs).
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
Quickstart
|
|
56
|
-
-----------
|
|
57
|
-
|
|
58
|
-
- Register for an account at [Sapling.ai](https://sapling.ai).
|
|
59
|
-
- After registering and signing in, generate a development API key in your [dashboard](https://sapling.ai/user_settings).
|
|
60
|
-
- Install the Python client by following the installation steps above.
|
|
61
|
-
|
|
62
|
-
```python
|
|
63
|
-
from sapling import SaplingClient
|
|
64
|
-
|
|
65
|
-
API_KEY = '<YOUR_API_KEY>'
|
|
66
|
-
client = SaplingClient(api_key=API_KEY)
|
|
67
|
-
edits = client.edits('Lets get started!', session_id='test_session')
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
The result should be an array of edits of this form:
|
|
71
|
-
|
|
72
|
-
```json
|
|
73
|
-
[{
|
|
74
|
-
"id": "aa5ee291-a073-5146-8ebc-c9c899d01278",
|
|
75
|
-
"sentence": "Lets get started!",
|
|
76
|
-
"sentence_start": 0,
|
|
77
|
-
"start": 0,
|
|
78
|
-
"end": 4,
|
|
79
|
-
"replacement": "Let's",
|
|
80
|
-
"error_type": "R:OTHER",
|
|
81
|
-
"general_error_type": "Other",
|
|
82
|
-
}]
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Get a production key by following [this documentation](https://sapling.ai/docs/api/api-access).
|
|
86
|
-
|
|
87
|
-
Here's some more information on [request options and response structure](https://sapling.ai/docs/api/edits-overview).
|
|
88
|
-
|
|
89
|
-
License
|
|
90
|
-
-------
|
|
91
|
-
|
|
92
|
-
Copyright 2022 Sapling Intelligence, Inc.
|
|
93
|
-
|
|
94
|
-
Licensed under the Apache License, Version 2.0.
|
sapling_py-4.0.2/README.md
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# Sapling Python Client
|
|
2
|
-
|
|
3
|
-
Python wrapper for the [Sapling.ai API](https://sapling.ai/api).
|
|
4
|
-
|
|
5
|
-
Try out a [grammar check demo](https://sapling.ai/grammar-check).
|
|
6
|
-
Compare against grammar checking tools and APIs like Grammarly (Grammerly), LanguageTool, ProWritingAid and Ginger.
|
|
7
|
-
|
|
8
|
-
Functionality
|
|
9
|
-
--------
|
|
10
|
-
|
|
11
|
-
Sapling is an AI messaging assistant.
|
|
12
|
-
The API currently offers spelling and grammar checking endpoints.
|
|
13
|
-
|
|
14
|
-
Benefits include:
|
|
15
|
-
- **60% more grammar corrections**: compared to [other systems](https://sapling.ai/comparison/api) at similar accuracy using state-of-the-art machine learning systems for natural language processing.
|
|
16
|
-
- **Low Latency**: Achieve the same real-time performance that users of Sapling's own interface experience.
|
|
17
|
-
- **Over 20 error types**: Error categories such as preposition, noun form, and verb tense, including both high-level and fine-grained error information.
|
|
18
|
-
- **Custom Models**: Get corrections and edits tuned to the domain of your text—for example academic writing vs. subtitles.
|
|
19
|
-
- **Enterprise Security**: Ask us about our no data retention policies, [self-hosted/on-premises](https://sapling.ai/onprem) deployment options, and other [cybersecurity policies and procedures](https://sapling.ai/security).
|
|
20
|
-
- **Rich Text Editor Support**: TinyMCE, CKEditor, QuillJS, Trix, ProseMirror, WordPress, Draft.js, Froala, Lexical and others. Consider using [Sapling's JavaScript SDK](https://sapling.ai/docs/sdk/JavaScript/quickstart) for displaying the API's outputs on webpage editors.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Installation
|
|
24
|
-
--------
|
|
25
|
-
|
|
26
|
-
Install the `sapling-py` package with [pip](https://pip.pypa.io/en/stable/installation/)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
python -m pip install sapling-py
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Documentation
|
|
35
|
-
-------------
|
|
36
|
-
|
|
37
|
-
Documentation for the client is available at [Read the Docs](https://sapling.readthedocs.io/) and
|
|
38
|
-
documentation for the HTTP API is available at [Sapling.ai](https://sapling.ai/docs).
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
Quickstart
|
|
42
|
-
-----------
|
|
43
|
-
|
|
44
|
-
- Register for an account at [Sapling.ai](https://sapling.ai).
|
|
45
|
-
- After registering and signing in, generate a development API key in your [dashboard](https://sapling.ai/user_settings).
|
|
46
|
-
- Install the Python client by following the installation steps above.
|
|
47
|
-
|
|
48
|
-
```python
|
|
49
|
-
from sapling import SaplingClient
|
|
50
|
-
|
|
51
|
-
API_KEY = '<YOUR_API_KEY>'
|
|
52
|
-
client = SaplingClient(api_key=API_KEY)
|
|
53
|
-
edits = client.edits('Lets get started!', session_id='test_session')
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
The result should be an array of edits of this form:
|
|
57
|
-
|
|
58
|
-
```json
|
|
59
|
-
[{
|
|
60
|
-
"id": "aa5ee291-a073-5146-8ebc-c9c899d01278",
|
|
61
|
-
"sentence": "Lets get started!",
|
|
62
|
-
"sentence_start": 0,
|
|
63
|
-
"start": 0,
|
|
64
|
-
"end": 4,
|
|
65
|
-
"replacement": "Let's",
|
|
66
|
-
"error_type": "R:OTHER",
|
|
67
|
-
"general_error_type": "Other",
|
|
68
|
-
}]
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Get a production key by following [this documentation](https://sapling.ai/docs/api/api-access).
|
|
72
|
-
|
|
73
|
-
Here's some more information on [request options and response structure](https://sapling.ai/docs/api/edits-overview).
|
|
74
|
-
|
|
75
|
-
License
|
|
76
|
-
-------
|
|
77
|
-
|
|
78
|
-
Copyright 2022 Sapling Intelligence, Inc.
|
|
79
|
-
|
|
80
|
-
Licensed under the Apache License, Version 2.0.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '4.0.2'
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: sapling-py
|
|
3
|
-
Version: 4.0.2
|
|
4
|
-
Summary: Sapling Python Client
|
|
5
|
-
Home-page: https://sapling.ai
|
|
6
|
-
Author: Sapling Intelligence
|
|
7
|
-
Author-email: info@sapling.ai
|
|
8
|
-
License: Apache License 2.0
|
|
9
|
-
Classifier: Development Status :: 3 - Alpha
|
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Description-Content-Type: text/markdown
|
|
12
|
-
License-File: LICENSE
|
|
13
|
-
Requires-Dist: requests
|
|
14
|
-
|
|
15
|
-
# Sapling Python Client
|
|
16
|
-
|
|
17
|
-
Python wrapper for the [Sapling.ai API](https://sapling.ai/api).
|
|
18
|
-
|
|
19
|
-
Try out a [grammar check demo](https://sapling.ai/grammar-check).
|
|
20
|
-
Compare against grammar checking tools and APIs like Grammarly (Grammerly), LanguageTool, ProWritingAid and Ginger.
|
|
21
|
-
|
|
22
|
-
Functionality
|
|
23
|
-
--------
|
|
24
|
-
|
|
25
|
-
Sapling is an AI messaging assistant.
|
|
26
|
-
The API currently offers spelling and grammar checking endpoints.
|
|
27
|
-
|
|
28
|
-
Benefits include:
|
|
29
|
-
- **60% more grammar corrections**: compared to [other systems](https://sapling.ai/comparison/api) at similar accuracy using state-of-the-art machine learning systems for natural language processing.
|
|
30
|
-
- **Low Latency**: Achieve the same real-time performance that users of Sapling's own interface experience.
|
|
31
|
-
- **Over 20 error types**: Error categories such as preposition, noun form, and verb tense, including both high-level and fine-grained error information.
|
|
32
|
-
- **Custom Models**: Get corrections and edits tuned to the domain of your text—for example academic writing vs. subtitles.
|
|
33
|
-
- **Enterprise Security**: Ask us about our no data retention policies, [self-hosted/on-premises](https://sapling.ai/onprem) deployment options, and other [cybersecurity policies and procedures](https://sapling.ai/security).
|
|
34
|
-
- **Rich Text Editor Support**: TinyMCE, CKEditor, QuillJS, Trix, ProseMirror, WordPress, Draft.js, Froala, Lexical and others. Consider using [Sapling's JavaScript SDK](https://sapling.ai/docs/sdk/JavaScript/quickstart) for displaying the API's outputs on webpage editors.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Installation
|
|
38
|
-
--------
|
|
39
|
-
|
|
40
|
-
Install the `sapling-py` package with [pip](https://pip.pypa.io/en/stable/installation/)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
python -m pip install sapling-py
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
Documentation
|
|
49
|
-
-------------
|
|
50
|
-
|
|
51
|
-
Documentation for the client is available at [Read the Docs](https://sapling.readthedocs.io/) and
|
|
52
|
-
documentation for the HTTP API is available at [Sapling.ai](https://sapling.ai/docs).
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
Quickstart
|
|
56
|
-
-----------
|
|
57
|
-
|
|
58
|
-
- Register for an account at [Sapling.ai](https://sapling.ai).
|
|
59
|
-
- After registering and signing in, generate a development API key in your [dashboard](https://sapling.ai/user_settings).
|
|
60
|
-
- Install the Python client by following the installation steps above.
|
|
61
|
-
|
|
62
|
-
```python
|
|
63
|
-
from sapling import SaplingClient
|
|
64
|
-
|
|
65
|
-
API_KEY = '<YOUR_API_KEY>'
|
|
66
|
-
client = SaplingClient(api_key=API_KEY)
|
|
67
|
-
edits = client.edits('Lets get started!', session_id='test_session')
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
The result should be an array of edits of this form:
|
|
71
|
-
|
|
72
|
-
```json
|
|
73
|
-
[{
|
|
74
|
-
"id": "aa5ee291-a073-5146-8ebc-c9c899d01278",
|
|
75
|
-
"sentence": "Lets get started!",
|
|
76
|
-
"sentence_start": 0,
|
|
77
|
-
"start": 0,
|
|
78
|
-
"end": 4,
|
|
79
|
-
"replacement": "Let's",
|
|
80
|
-
"error_type": "R:OTHER",
|
|
81
|
-
"general_error_type": "Other",
|
|
82
|
-
}]
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Get a production key by following [this documentation](https://sapling.ai/docs/api/api-access).
|
|
86
|
-
|
|
87
|
-
Here's some more information on [request options and response structure](https://sapling.ai/docs/api/edits-overview).
|
|
88
|
-
|
|
89
|
-
License
|
|
90
|
-
-------
|
|
91
|
-
|
|
92
|
-
Copyright 2022 Sapling Intelligence, Inc.
|
|
93
|
-
|
|
94
|
-
Licensed under the Apache License, Version 2.0.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
requests
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|