Skip to content

Commit

Permalink
[ADD] methods to response and sentence; [UPD] init, client and entities
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulRenvoise committed Jun 28, 2016
1 parent 6bcf9ee commit e104ce4
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 57 deletions.
71 changes: 41 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,54 +35,61 @@ pip install recastai
```python
import recastai

client = Client(YOUR_TOKEN)
client = Client(YOUR_TOKEN, YOUR_LANGUAGE)
response = client.text_request(YOUR_TEXT)
#response = client.file_request(open(YOUR_FILE, 'rb'))
"""response = client.file_request(open(YOUR_FILE, 'rb'))"""

if (response.intent is YOUR_EXPECTED_INTENT):
# Do your code...
if (response.intent == YOUR_EXPECTED_INTENT):
"""Do your code..."""
```

## Specs

### Classes

This module contains 5 main classes, as follows:
This library contains 5 main classes, as follows:

* Client is the client allowing you to make requests.
* Response contains the response from [Recast.AI](https://recast.ai).
* Sentence represents a sentence of the response.
* Entity represents an entity found by Recast.AI in your user's input.
* RecastError is the error thrown by the gem.
* RecastError is the error thrown by the library.

Don't hesitate to dive into the code, it's commented ;)

### Client

The Recast.AI Client can be instanciated with a token and provides the two following methods:
The Recast.AI Client can be instanciated with a token (optional) and a language (optional) and provides the two following methods:

* text_request(text, \*\*options) *Performs a text request*
* file_request(file, \*\*options) *Performs a voice file request*

*Accepted options are 'token', to override the default token provided at initialization*
On each call to `text_request` or `file_request` your can override either your token or your language by passing a hash of options.

```ruby
If no language is provided in the request, Recast.AI does the following:

* text_request: the language of the text is detected and is used for processing if your bot has expressions for it, else your bot's primary language is used for processing.
* voice_request: your bot's primary language is used for processing as we do not provide language detection for speech.

*Accepted options are :token, :language, to override the defaults provided at initialization*

```python
import recastai

client = Client(YOUR_TOKEN)
client = Client(YOUR_TOKEN, YOUR_LANGUAGE)

# Performs a text request on Recast.AI
response = client.text_request(YOUR_TEXT)
"""Performs a text request on Recast.AI"""
response = client.text_request(YOUR_TEXT, {'token':YOUR_TOKEN, 'language':YOUR_LANGUAGE})

if response.intent is YOUR_EXPECTED_INTENT
if response.intent == YOUR_EXPECTED_INTENT
# Do your code...
end

# Performs a voice file request on Recast.AI
response = client.file_request(open(YOUR_FILE, 'rb'), { token: YOUR_TOKEN }) # TODO
"""Performs a voice file request on Recast.AI""
response = client.file_request(open(YOUR_FILE, 'rb'), {'token':YOUR_TOKEN, 'language':YOUR_LANGUAGE })
if response.intent is YOUR_EXPECTED_INTENT
# Do your code...
if response.intent == YOUR_EXPECTED_INTENT
"""Do your code..."""
end
```
Expand All @@ -98,22 +105,24 @@ The Recast.AI Response is generated after a call with the two previous methods a
* sentence(\*) *Returns the first detected sentence*
* get(name) *Returns the first entity matching -name-*
* all(name) *Returns all the entities matching -name-*
* version(\*) *Returns the version of the JSON*
* entities(\*) *Returns all the entities*
* language(\*) *Returns the language of the processed sentence*
* version(\*) *Returns the version of the API*
* timestamp(\*) *Returns the timestamp at the end of the processing*
* status(\*) *Returns the status of the response*
```ruby
```python
response = client.text_request('Give me some recipes with potatoes. And cheese.')
# Get the first sentence, aka 'Give me some recipes with potatoes'
first_sentence = response.sentence
# If the first intent matched 'recipe'...
if response.intent is 'recipe'
# ...get all the entities matching 'ingredient'
"""If the first intent matched 'recipe'..."""
if response.intent == 'recipe'
"""...get all the entities matching 'ingredient'"""
ingredients = response.all('ingredient')
puts "The request has been filled at #{response.timestamp}"
puts "The request has been filled at " + response.timestamp
end
```
Expand All @@ -126,15 +135,17 @@ The Recast.AI Sentence is generated by the Recast.AI Response initializer and pr
* action(\*) *Returns the action of the sentence*
* agent(\*) *Returns the agent of the sentence*
* polarity(\*) *Returns the polarity (negation or not) of the sentence*
* get(name) *Returns the first entity matching -name-*
* all(name) *Returns all the entities matching -name-*
* entities(\*) *Returns all the entities detected in the sentence*
```ruby
```python
response = client.text_request('Tell me a joke.')
# Get the first sentence
"""Get the first sentence"""
sentence = response.sentence
if sentence.action is 'tell' && sentence.polarity is 'positive'
# Tell a joke...
if sentence.action == 'tell' and sentence.polarity == 'positive'
"""Tell a joke..."""
end
```
Expand Down Expand Up @@ -165,11 +176,11 @@ In addition to this method, more attributes are generated depending of the natur
```ruby
response = client.text_request('What can I cook with salmon ?')
if response.intent is 'recipe'
# Get the ingredient
if response.intent == 'recipe'
"""Get the ingredient"""
ingredient = response.get('ingredient')
puts "You asked me for a recipe with #{ingredient.value}"
puts "You asked me for a recipe with " + ingredient.value
end
```
Expand Down
10 changes: 9 additions & 1 deletion recastai/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# -*- coding: utf-8 -*-

from recastai import client
import json
import requests

from .client import Client
from .response import Response
from .sentence import Sentence
from .entity import Entity
from .errors import RecastError
from .utils import Utils
55 changes: 39 additions & 16 deletions recastai/client.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,60 @@
from recastai import utils
from recastai import errors
from recastai import response
# -*- coding: utf-8 -*-

import requests

from .response import Response
from .errors import RecastError
from .utils import Utils

class Client(object):
def __init__(self, token=None):
def __init__(self, token=None, language=None):
self.token = token
self.language = language

"""
Perform a text request to Recast.AI
"""
def text_request(self, text, **options):
token = options.get('token') or self.token
if token is None:
raise RecastError('Token is missing')
raise RecastError("Token is missing")

language = options.get('language') or self.language

response = requests.post("{url}/request".format(url=self.url),
params={'text': text},
headers={'Authorization': 'Token ' + token}
body = {'text': text}
if language is not None:
body['language'] = language

response = requests.post(Utils.API_ENDPOINT,
params=body,
headers={'Authorization': "Token " + token}
)
if response.status_code != 200:
if response.status_code != requests.codes.ok:
raise RecastError(response.message)

return Response(response.body)
print(response.text)
return Response(response.text)

"""
Perform a text request to Recast.AI
"""
def file_request(self, file, **options):
token = options.get('token') or self.token
if token == None:
raise RecastError('Token is missing')
raise RecastError("Token is missing")

language = options.get('language') or self.language

file = open(file, 'rb') if (type(file) is str) else file
body = {'voice': file}
if language is not None:
body['language'] = language

response = requests.post("{url}/request".format(url=self.url),
files={'voice':file},
headers={'Authorization': 'Token ' + token}
response = requests.post(Utils.API_ENDPOINT,
files=body,
headers={'Authorization': "Token " + token}
)
if response.status_code != 200:
if response.status_code != requests.codes.ok:
raise RecastError(response.message)

return Response(response.body)
return Response(response.text)
4 changes: 3 additions & 1 deletion recastai/entity.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-

class Entity(object):
def __init__(self, name, data):
self.name = name

for k, v in data.iteritems():
for k, v in data.items():
setattr(self, k, v)
2 changes: 2 additions & 0 deletions recastai/errors.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# -*- coding: utf-8 -*-

class RecastError(Exception):
pass
18 changes: 15 additions & 3 deletions recastai/response.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-

import json
from recastai import sentence

from .sentence import Sentence

class Response(object):
def __init__(self, response):
Expand All @@ -11,6 +14,7 @@ def __init__(self, response):
self.source = response['source']
self.intents = response['intents']
self.sentences = [Sentence(s) for s in response['sentences']]
self.language = response['language']
self.version = response['version']
self.timestamp = response['timestamp']
self.status = response['status']
Expand All @@ -33,13 +37,21 @@ def get(self, name):
if (entity.name.lower() == name.lower()):
return entity


def all(self, name=None):
entities = []

for sentence in self.sentences:
for entity in sentence.entities:
if (name is None) or (entity.name.lower() == name.lower()):
if (name is not None) and (entity.name.lower() == name.lower()):
entities.append(entity)

return entities

def entities(self):
entities = []

for sentence in self.sentences:
for entity in sentence.entities:
entities.append(entity)

return entities
20 changes: 18 additions & 2 deletions recastai/sentence.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from recastai import entity
# -*- coding: utf-8 -*-

from .entity import Entity

class Sentence(object):
def __init__(self, sentence):
Expand All @@ -7,4 +9,18 @@ def __init__(self, sentence):
self.action = sentence['action']
self.agent = sentence['agent']
self.polarity = sentence['polarity']
self.entities = [Entity(n, ee) for ee in e for n, e in sentence['entities']]
self.entities = [Entity(n, ee) for n, e in sentence['entities'].items() for ee in e]

def get(self, name):
for entity in self.entities:
if (entity.name.lower() == name.lower()):
return entity

def all(self, name=None):
entities = []

for entity in self.entities:
if (name is not None) and (entity.name.lower() == name.lower()):
entities.append(entity)

return entities
8 changes: 5 additions & 3 deletions recastai/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# -*- coding: utf-8 -*-

class Utils(object):
# Versioning
"""Versioning"""
MAJOR = '1'
MINOR = '0'
MICRO = '2'
MICRO = '0'
VERSION = "{0}.{1}.{2}".format(MAJOR, MINOR, MICRO)

# Endpoints
"""Endpoints"""
API_ENDPOINT = 'https://api.recast.ai/v1/request'
WS_ENDPOINT = 'wss://api.recast.ai/v1/request'
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
requests==2.10.0
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from distutils.core import setup
from setuptools import setup

setup(
name="recastai",
Expand Down

0 comments on commit e104ce4

Please sign in to comment.