diff --git a/language/snippets/tutorial/README.rst.in b/language/snippets/tutorial/README.rst.in new file mode 100644 index 000000000000..aea593b277f4 --- /dev/null +++ b/language/snippets/tutorial/README.rst.in @@ -0,0 +1,20 @@ +# This file is used to generate README.rst + +product: + name: Google Cloud Natural Language Tutorial + short_name: Cloud Natural Language Tutorial + url: https://cloud.google.com/natural-language/docs/ + description: > + The `Google Cloud Natural Language API`_ provides natural language + understanding technologies to developers, including sentiment analysis, + entity recognition, and syntax analysis. This API is part of the larger + Cloud Machine Learning API. + +setup: +- auth +- install_deps + +samples: +- name: Language tutorial + file: tutorial.py + show_help: true diff --git a/language/snippets/tutorial/requirements.txt b/language/snippets/tutorial/requirements.txt new file mode 100644 index 000000000000..2cd2a1334ea0 --- /dev/null +++ b/language/snippets/tutorial/requirements.txt @@ -0,0 +1 @@ +google-api-python-client==1.5.5 diff --git a/language/snippets/tutorial/reviews/bladerunner-mixed.txt b/language/snippets/tutorial/reviews/bladerunner-mixed.txt new file mode 100644 index 000000000000..3b520b65a8a7 --- /dev/null +++ b/language/snippets/tutorial/reviews/bladerunner-mixed.txt @@ -0,0 +1,19 @@ +I really wanted to love 'Bladerunner' but ultimately I couldn't get +myself to appreciate it fully. However, you may like it if you're into +science fiction, especially if you're interested in the philosophical +exploration of what it means to be human or machine. Some of the gizmos +like the flying cars and the Vouight-Kampff machine (which seemed very +steampunk), were quite cool. + +I did find the plot pretty slow and but the dialogue and action sequences +were good. Unlike most science fiction films, this one was mostly quiet, and +not all that much happened, except during the last 15 minutes. I didn't +understand why a unicorn was in the movie. The visual effects were fantastic, +however, and the musical score and overall mood was quite interesting. +A futurist Los Angeles that was both highly polished and also falling apart +reminded me of 'Outland.' Certainly, the style of the film made up for +many of its pedantic plot holes. + +If you want your sci-fi to be lasers and spaceships, 'Bladerunner' may +disappoint you. But if you want it to make you think, this movie may +be worth the money. \ No newline at end of file diff --git a/language/snippets/tutorial/reviews/bladerunner-neg.txt b/language/snippets/tutorial/reviews/bladerunner-neg.txt new file mode 100644 index 000000000000..dbef76271d16 --- /dev/null +++ b/language/snippets/tutorial/reviews/bladerunner-neg.txt @@ -0,0 +1,3 @@ +What was Hollywood thinking with this movie! I hated, +hated, hated it. BORING! I went afterwards and demanded my money back. +They refused. \ No newline at end of file diff --git a/language/snippets/tutorial/reviews/bladerunner-neutral.txt b/language/snippets/tutorial/reviews/bladerunner-neutral.txt new file mode 100644 index 000000000000..60556e604be9 --- /dev/null +++ b/language/snippets/tutorial/reviews/bladerunner-neutral.txt @@ -0,0 +1,2 @@ +I neither liked nor disliked this movie. Parts were interesting, but +overall I was left wanting more. The acting was pretty good. \ No newline at end of file diff --git a/language/snippets/tutorial/reviews/bladerunner-pos.txt b/language/snippets/tutorial/reviews/bladerunner-pos.txt new file mode 100644 index 000000000000..a7faf81570b3 --- /dev/null +++ b/language/snippets/tutorial/reviews/bladerunner-pos.txt @@ -0,0 +1,10 @@ +`Bladerunner` is often touted as one of the best science fiction films ever +made. Indeed, it satisfies many of the requisites for good sci-fi: a future +world with flying cars and humanoid robots attempting to rebel against their +creators. But more than anything, `Bladerunner` is a fantastic exploration +of the nature of what it means to be human. If we create robots which can +think, will they become human? And if they do, what makes us unique? Indeed, +how can we be sure we're not human in any case? `Bladerunner` explored +these issues before such movies as `The Matrix,' and did so intelligently. +The visual effects and score by Vangelis set the mood. See this movie +in a dark theatre to appreciate it fully. Highly recommended! \ No newline at end of file diff --git a/language/snippets/tutorial/tutorial.py b/language/snippets/tutorial/tutorial.py new file mode 100644 index 000000000000..b2ac2421a5be --- /dev/null +++ b/language/snippets/tutorial/tutorial.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python + +# Copyright 2016 Google, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# [START full_tutorial_script] +# [START import_libraries] +import argparse +import io + +from googleapiclient import discovery +from oauth2client.client import GoogleCredentials +# [END import_libraries] + + +def print_sentiment(filename): + """Prints sentiment analysis on a given file contents.""" + # [START authenticating_to_the_api] + credentials = GoogleCredentials.get_application_default() + service = discovery.build('language', 'v1', credentials=credentials) + # [END authenticating_to_the_api] + + # [START constructing_the_request] + with io.open(filename, 'r') as review_file: + review_file_contents = review_file.read() + + service_request = service.documents().analyzeSentiment( + body={ + 'document': { + 'type': 'PLAIN_TEXT', + 'content': review_file_contents, + } + } + ) + response = service_request.execute() + # [END constructing_the_request] + + # [START parsing_the_response] + score = response['documentSentiment']['score'] + magnitude = response['documentSentiment']['magnitude'] + + for n, sentence in enumerate(response['sentences']): + sentence_sentiment = sentence['sentiment']['score'] + print('Sentence {} has a sentiment score of {}'.format(n, + sentence_sentiment)) + + print('Overall Sentiment: score of {} with magnitude of {}'.format( + score, magnitude)) + # [END parsing_the_response] + + +# [START running_your_application] +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument( + 'movie_review_filename', + help='The filename of the movie review you\'d like to analyze.') + args = parser.parse_args() + print_sentiment(args.movie_review_filename) +# [END running_your_application] +# [END full_tutorial_script] diff --git a/language/snippets/tutorial/tutorial_test.py b/language/snippets/tutorial/tutorial_test.py new file mode 100644 index 000000000000..065076fb4cc7 --- /dev/null +++ b/language/snippets/tutorial/tutorial_test.py @@ -0,0 +1,51 @@ +# Copyright 2016, Google, Inc. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import re + +import tutorial + + +def test_neutral(capsys): + tutorial.print_sentiment('reviews/bladerunner-neutral.txt') + out, _ = capsys.readouterr() + assert re.search(r'Sentence \d has a sentiment score of \d', out, re.I) + assert re.search( + r'Overall Sentiment: score of -?[0-2]\.?[0-9]? with ' + r'magnitude of [0-1]\.?[0-9]?', out, re.I) + + +def test_pos(capsys): + tutorial.print_sentiment('reviews/bladerunner-pos.txt') + out, _ = capsys.readouterr() + assert re.search(r'Sentence \d has a sentiment score of \d', out, re.I) + assert re.search( + r'Overall Sentiment: score of [0-9]\.?[0-9]? with ' + r'magnitude of [0-9]\.?[0-9]?', out, re.I) + + +def test_neg(capsys): + tutorial.print_sentiment('reviews/bladerunner-neg.txt') + out, _ = capsys.readouterr() + assert re.search(r'Sentence \d has a sentiment score of \d', out, re.I) + assert re.search( + r'Overall Sentiment: score of -[0-9]\.?[0-9]? with ' + r'magnitude of [2-7]\.?[0-9]?', out, re.I) + + +def test_mixed(capsys): + tutorial.print_sentiment('reviews/bladerunner-mixed.txt') + out, _ = capsys.readouterr() + assert re.search(r'Sentence \d has a sentiment score of \d', out, re.I) + assert re.search( + r'Overall Sentiment: score of -?[0-9]\.?[0-9]? with ' + r'magnitude of [3-6]\.?[0-9]?', out, re.I)