Skip to content

Commit d250825

Browse files
Merge pull request #218 from jeffpk62/master
Tone Analyzer: Add support for JSON and HTML input to tone() method
2 parents 272412e + 66761b9 commit d250825

5 files changed

Lines changed: 108 additions & 22 deletions

File tree

examples/tone_analyzer_v3.py

100644100755
Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,45 @@
11
import json
2+
import os
3+
from os.path import join, dirname
24
from watson_developer_cloud import ToneAnalyzerV3
35

4-
56
tone_analyzer = ToneAnalyzerV3(
67
username='YOUR SERVICE USERNAME',
78
password='YOUR SERVICE PASSWORD',
8-
version='2016-02-11')
9-
10-
print(json.dumps(tone_analyzer.tone(text='I am very happy'), indent=2))
9+
version='2016-05-19')
1110

12-
utterances = [{'text': 'I am very happy', 'user': 'glenn'}]
11+
print("\ntone_chat() example 1:\n")
12+
utterances = [{'text': 'I am very happy.', 'user': 'glenn'},
13+
{'text': 'It is a good day.', 'user': 'glenn'}]
1314
print(json.dumps(tone_analyzer.tone_chat(utterances), indent=2))
15+
16+
print("\ntone() example 1:\n")
17+
print(json.dumps(tone_analyzer.tone(text='I am very happy. It is a good day.'),
18+
indent=2))
19+
20+
print("\ntone() example 2:\n")
21+
with open(join(dirname(__file__),
22+
'../resources/tone-example.json')) as tone_json:
23+
tone = tone_analyzer.tone(json.load(tone_json)['text'], 'emotion')
24+
print(json.dumps(tone, indent=2))
25+
26+
print("\ntone() example 3:\n")
27+
with open(join(dirname(__file__),
28+
'../resources/tone-example.json')) as tone_json:
29+
tone = tone_analyzer.tone(json.load(tone_json)['text'], 'emotion',
30+
True, 'text/plain')
31+
print(json.dumps(tone, indent=2))
32+
33+
print("\ntone() example 4:\n")
34+
with open(join(dirname(__file__),
35+
'../resources/tone-example.json')) as tone_json:
36+
tone = tone_analyzer.tone(json.load(tone_json), 'emotion',
37+
content_type='application/json', )
38+
print(json.dumps(tone, indent=2))
39+
40+
print("\ntone() example 5:\n")
41+
with open(join(dirname(__file__),
42+
'../resources/tone-example-html.json')) as tone_json:
43+
tone = tone_analyzer.tone(json.load(tone_json)['text'], 'emotion',
44+
content_type='text/html')
45+
print(json.dumps(tone, indent=2))

resources/tone-example-html.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"text": "<p>Team, I know that times are tough!</p> <p>Product sales have been disappointing for the past three quarters.</p> <p>We have a competitive product, but <b>we need to do a better job of selling it!</b></p>"
3+
}

resources/tone-example.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"text": "Team, I know that times are tough! Product sales have been disappointing for the past three quarters. We have a competitive product, but we need to do a better job of selling it!"
3+
}

test/test_tone_analyzer_v3.py

100644100755
Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,35 @@ def test_tone_with_args():
4545
username="username", password="password")
4646
tone_analyzer.tone(tone_text.read(), tones="social", sentences=False)
4747

48+
assert responses.calls[0].request.url.split('?')[0] == tone_url
49+
# Compare args. Order is not deterministic!
50+
actualArgs = {}
51+
for arg in responses.calls[0].request.url.split('?')[1].split('&'):
52+
actualArgs[arg.split('=')[0]] = arg.split('=')[1]
53+
assert actualArgs == tone_args
54+
assert responses.calls[0].response.text == tone_response
55+
assert len(responses.calls) == 1
56+
57+
58+
@responses.activate
59+
## Invoking tone() with some modifiers specified as positional parameters: tones are emotion and social, and sentences is false
60+
def test_tone():
61+
tone_url = 'https://gateway.watsonplatform.net/tone-analyzer/api/v3/tone'
62+
tone_args = { 'version': '2016-05-19', 'tones': 'emotion%2Csocial', 'sentences': 'false' }
63+
tone_response = None
64+
with open(os.path.join(os.path.dirname(__file__), '../resources/tone-v3-expect1.json')) as response_json:
65+
tone_response = response_json.read()
66+
67+
responses.add(responses.POST, tone_url,
68+
body=tone_response, status=200,
69+
content_type='application/json')
70+
71+
with open(os.path.join(os.path.dirname(__file__), '../resources/personality.txt')) as tone_text:
72+
tone_analyzer = watson_developer_cloud.ToneAnalyzerV3("2016-05-19",
73+
username="username", password="password")
74+
tone_analyzer.tone(tone_text.read(), 'emotion,social', False)
4875

49-
assert responses.calls[0].request.url.split('?')[0] == tone_url
76+
assert responses.calls[0].request.url.split('?')[0] == tone_url
5077
# Compare args. Order is not deterministic!
5178
actualArgs = {}
5279
for arg in responses.calls[0].request.url.split('?')[1].split('&'):
@@ -55,6 +82,7 @@ def test_tone_with_args():
5582
assert responses.calls[0].response.text == tone_response
5683
assert len(responses.calls) == 1
5784

85+
5886
@responses.activate
5987
## Invoking tone_chat()
6088
def test_tone_chat():

watson_developer_cloud/tone_analyzer_v3.py

100644100755
Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
from .watson_developer_cloud_service import WatsonDeveloperCloudService
3030

31-
3231
class ToneAnalyzerV3(WatsonDeveloperCloudService):
3332
"""Client for the ToneAnalyzer service."""
3433

@@ -44,27 +43,48 @@ def __init__(self, version, url=default_url, **kwargs):
4443
# tone
4544
#########################
4645

47-
def tone(self, text, tones=None, sentences=None):
46+
def tone(self, text, tones=None, sentences=None, content_type='text/plain'):
4847
"""
49-
The tone API is the main API call: it analyzes the "tone" of a piece
50-
of text. The message is analyzed from
51-
several tones (social tone, emotional tone, writing tone), and for
52-
each of them various traits are derived
53-
(such as conscientiousness, agreeableness, openness).
54-
:param text: Text to analyze
55-
:param sentences: If "false", sentence-level analysis is omitted
56-
:param tones: Can be one or more of 'social', 'language', 'emotion';
57-
comma-separated.
48+
The general purpose tone API analyzes the "tone" of input text.
49+
The message is analyzed for several tones (social, emotional, and
50+
writing), with various characteristics derived for each tone.
51+
:param text: The input content to analyze.
52+
:param sentences: If false, sentence-level analysis is omitted; by
53+
default (or if true), each sentence is analyzed.
54+
:param tones: A comma-separated list of one or more of the following
55+
tones for which to analyze the input text, 'social', 'language', and
56+
'emotion'; the default is all tones.
57+
:param content_type: The type of the input content: "text/plain"
58+
(the default), "text/html", or "application/json".
5859
"""
60+
5961
params = {'version': self.version}
6062
if tones is not None:
6163
params['tones'] = tones
6264
if sentences is not None:
63-
params['sentences'] = str(
64-
sentences).lower() # Cast boolean to "false" / "true"
65-
data = {'text': text}
66-
return self.request(method='POST', url='/v3/tone', params=params,
67-
json=data, accept_json=True)
65+
# Cast boolean to "false" / "true"
66+
params['sentences'] = str(sentences).lower()
67+
if content_type == 'text/plain':
68+
text = {'text': text}
69+
content_type = 'application/json'
70+
headers = {'content-type': content_type}
71+
72+
if content_type == 'application/json':
73+
return self.request(
74+
method='POST', headers=headers, url='/v3/tone', params=params,
75+
json=text, accept_json=True)
76+
77+
# Use the equivalent of an 'else' rather than checking for explicit
78+
# 'text/html' so that the call is made and returns a meaningful error
79+
# for an invalid content type.
80+
if content_type != 'application/json':
81+
return self.request(
82+
method='POST', headers=headers, url='/v3/tone', params=params,
83+
data=text, accept_json=True)
84+
85+
#########################
86+
# tone_chat
87+
#########################
6888

6989
def tone_chat(self, utterances):
7090
"""

0 commit comments

Comments
 (0)