GutenReader is an app built in React Native for reading books hosted by Project Gutenberg. This microservice allows the app to play music that matches the current mood of the page the user is reading. GutenReader also uses a Rails API to handle database interaction.
NOTE: If running locally, you will need to create an account with IMB Cloud. Once you create the account, from your user dashboard click 'Create Resource' and then select 'Natural Language Understanding'. Click 'Create' and obtain the resource's API Key and URL. In the Flask .env file, set the API Key equal to WATSON_API
and the URL to WATSON_URL
.
Clone the repository
$ git clone git@github.com:Guten-Reader/guten_reader_BE.git
Create/activate virtual environment
$ virtualenv venv --python=python3.7
$ source venv/bin/activate
Install dependencies
$ pip install -r requirements.txt
Start the server in development environment
$ export APP_SETTINGS="config.TestingConfig"
$ python app.py
Run the tests
$ nose2
https://micro-guten.herokuapp.com/
POST api/v1/recommendation
Description: A user turns a new page in their Gutenberg book. A GET request is sent to /api/v1/recommendation
. The request includes the user's access_token
, the current_mood
, the music genre
and the new page's full text
in the request body.
The endpoint conducts a sentiment analysis on the text and returns a value of either 1(Positive), 0.5(Neutral), or 0(Negative) internally. The sentiment value and access_token is used to call Spotify's track recommendation endpoint. The track recommendation endpoint returns an array of 10 classical tracks (as track_uri) with the mood value (1, 0.5, 0).
The body of the request requires an access_token. You can obtain an access_token by visiting the access_token endpoint on our Rails app. Access_token expires hourly.
Request
POST /api/v1/recommendation
Content-Type: application/json
Accept: application/json
{
"current_mood": 0.5,
"text": "This is a very happy and positive statement.",
"access_token": "BQCUhf-kwMIv9TrDe9boSzrRr-Z6xmuPLoqTAgEyJDJD6G4HIMlQHgRX6BWllCfIxOpK2kQQCiHDsqa3svALu0jPyuAnw6-dn1tjkpB1SSAGL6ma3Q1ZIegcIfKS1v4ag-Gb8uUKc9ch5tt20vazj_PXmK0",
"genre": "classical"
}
Successful Response - If new page has DIFFERENT MOOD than current_mood
status: 200
{
"mood": 1,
"recommended_tracks": [
"spotify:track:0qkMYjXnxz91fEnnuMZNi0",
"spotify:track:2LhRrWfxTV6ZW1XAOb2OGa",
"spotify:track:6ZFbXIJkuI1dVNWvzJzown",
"spotify:track:4m5rO8vfR0H6V4J8sKTU2J",
"spotify:track:4HBMnZFquWVTATSjTABueZ",
"spotify:track:7AE8dFDObE3tbl8JloJVJD",
"spotify:track:4tomnQKFLdhCYOtTSmlv4Q",
"spotify:track:0abApP5Xl9PVwuE0Vo4Oyz",
"spotify:track:1ZNlk8aE9BhgCxTlm53KAX",
"spotify:track:5rSR9a0inBSyYlNTLa8BLi"
],
"status_code": 200
}
Successful Response - If new page has SAME MOOD than current_mood
status: 204
NO CONTENT
Unsuccessful Response - If access_token expired
status: 401
{
"message": "The access token expired",
"status_code": 401
}
Unsuccessful Response - If invalid body request. Missing access_token, current_mood, genre and/or text
status: 400
{
"error": {
"missing_params": [
"current_mood",
"access_token",
"genre",
"text"
]
}
}
Unsuccessful Response - If invalid request by Spotify external API call
status: 400
{
"error": "invalid request"
}