Skip to content

Commit

Permalink
Update app.py with working search endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mvkumar14 committed Mar 6, 2020
1 parent b18f1ce commit ad19696
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -51,7 +51,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -60,33 +60,13 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"response = requests.get('https://www.googleapis.com/books/v1/volumes?q=flowers+inauthor:keyes&key='+GOOGLE_KEY)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Response [200]>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"response"
]
},
{
"cell_type": "code",
"execution_count": 12,
Expand Down Expand Up @@ -2040,6 +2020,18 @@
"source": [
"process_list(sample_api_result['items'],relevant_details)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Importing ENV variables instead of secrets.py\n",
"This is simply syntax reference because jupyter notebook environment doen't have a .env file like a pipenv does. In the final product this is probably what we are going to be doing because we can load in environment variables to elastic beanstalk\n",
"```\n",
"import os\n",
"GOOGLE_KEY = os.environ['GOOGLE_KEY']\n",
"```"
]
}
],
"metadata": {
Expand Down
1 change: 1 addition & 0 deletions APIs/Google_Books/.ipynb_checkpoints/secrets-checkpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GOOGLE_KEY = 'AIzaSyA7fR1aXn1w55nzQa17Y1xHjNCYwTx9LvI'
38 changes: 15 additions & 23 deletions APIs/Google_Books/Google_books_test.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -51,7 +51,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -60,33 +60,13 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"response = requests.get('https://www.googleapis.com/books/v1/volumes?q=flowers+inauthor:keyes&key='+GOOGLE_KEY)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Response [200]>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"response"
]
},
{
"cell_type": "code",
"execution_count": 12,
Expand Down Expand Up @@ -2040,6 +2020,18 @@
"source": [
"process_list(sample_api_result['items'],relevant_details)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Importing ENV variables instead of secrets.py\n",
"This is simply syntax reference because jupyter notebook environment doen't have a .env file like a pipenv does. In the final product this is probably what we are going to be doing because we can load in environment variables to elastic beanstalk\n",
"```\n",
"import os\n",
"GOOGLE_KEY = os.environ['GOOGLE_KEY']\n",
"```"
]
}
],
"metadata": {
Expand Down
Binary file modified APIs/Google_Books/__pycache__/secrets.cpython-37.pyc
Binary file not shown.
72 changes: 72 additions & 0 deletions BetterReadsDS/.ipynb_checkpoints/app-checkpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Inbuild Modules
import os
import json

# Third Party Modules
import requests
from flask import Flask, render_template, request, jsonify
# from decouple import config #<-- not sure what this does yet

# Custom Modules
from google_books_hf import process_list

# Retreive Google API key from environment


def create_app():
app = Flask(__name__)

# Whenever we output a list of books the json format of the
# list should be the same. Lets call this format
# OUT_LIST format for now. This format is what the Web team is
# currently using to render book list results.


@app.route('/')
# some details about the api and some references
# to api documentation
def root():
return render_template('base.html',page_name='home')
@app.route('/search/<search_term>')

# the input is going to be a string
# output will be a list of books from the google api
# formatting of the output should be in OUT_LIST format
def search(search_term):
GOOGLE_KEY = os.environ['GOOGLE_KEY']
response = requests.get('https://www.googleapis.com/books/v1/volumes?q='
+ search_term
+ '&key='
+ GOOGLE_KEY)
result = json.loads(response.text)

relevant_details=['id','title','authors','publisher',
'publishedDate','description','industryIdentifiers',
'pageCount','categories','thumbnail','smallThumbnail',
'language','webReaderLink','textSnippet','isEbook']

output = process_list(result['items'],relevant_details)
return jsonify(output)

@app.route('/subject_list')
# input will be subject heading (this should be a valid value)
# We need to give BE/FE a list of valid subject headings
# output is going to be a list of books in the OUT_LIST format
def subjects():
return render_template('base.html',page_name='subjects')


@app.route('/recommendations')
# input is ???
# The input might include parameters that aid in the model
# selection process. We may have different models depending on
# the different types of recommendations we need to provide.
# output is a list of books.
def recommendations():
return render_template('base.html',page_name='recommendations')


return app

if __name__=="__main__":
print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
111 changes: 111 additions & 0 deletions BetterReadsDS/.ipynb_checkpoints/google_books_hf-checkpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"""
This module is a set of helper functions to process data from the google
books API. The functions are as follows:
retreive_details() - Retreive specific keys from a dictionary object
clean() - Alter data to match data model
process_list() - Process a list of dictionaries to endpoint output format
"""
import pickle
import requests
import json

# This is a general function. Should work on any JSON data
def retreive_details(input_dict,keys_to_extract):
"""
Retreive specific keys from a dictionary object
This function searches through a dictionary, and
retreives keys that match keys from a list. This function
will find matching keys in every level of the dictionary heirarchy.
Inputs:
input_dict - A dictionary (expected to be from json.loads()
in the context of BetterReads, but the function
will work on any dictionary).
keys_to_extract - A list of keys that you want to extract from the
json_dict object.
Output:
new_dict - A new "flattened"dictionary with all the matching keys.
All the keys are in the top level.
"""

new_dict={}
for item in input_dict.keys():
if type(input_dict[item]) is dict:
temp_dict = retreive_details(input_dict[item],keys_to_extract)
new_dict.update(temp_dict)
if item in keys_to_extract:
new_dict[item] = input_dict[item]
return new_dict

# The following functions are specific to the BetterReads Project
def clean(input_dict):
"""
Alter data to match data model
This function reformats isbns, and modifies the id name
from a dictionary returned from retreive_details. It also
changes the id key to googleId to match the format that the
API endpoint specifies.
Input:
input_dict - a dictionary output from retreive_details using
the list of keys required for the BetterReadsDS
API response.
Output:
output_dict - a dictionary ready to send as a response to a
request received by the server.
"""

my_dict = {}

# Change the format of the isbn data
try:
for i in input_dict['industryIdentifiers']:
my_dict[("".join(i['type'].split('_')).lower())] = i['identifier']

# Add isbns to dictionary and remove the industryIdentifiers key
input_dict.update(my_dict)
del input_dict['industryIdentifiers']
except KeyError:
pass

# Change id to googleId
# Try/except should not be necessary here.
# Google Books always returns an id
input_dict['googleId']=input_dict['id']
del input_dict['id']

output_dict = input_dict
return output_dict

def process_list(list_of_entries,keys_to_extract):
"""
Process a list of dictionaries to endpoint output format
This function takes a list of dictionaries, extracts the keys
specified, and then cleans the resulting list of dictionaries.
See the clean function for details on what "cleaning" entails.
Inputs:
list_of_entries - A list of dictonaries from the Google Books API.
keys_to_extract - A list of keys that you want to extract from the
json_dict object.
Outputs:
out_list - a list of dictionaries containing book entries.
"""
out_list = []
for i in list_of_entries:
parsed_dict = retreive_details(i,keys_to_extract)
clean_dict = clean(parsed_dict)
out_list.append(clean_dict)
return out_list
31 changes: 27 additions & 4 deletions BetterReadsDS/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Inbuild Modules
import os
import json

# Third Party Modules
import requests
from flask import Flask, render_template, request, jsonify
# from decouple import config #<-- not sure what this does yet
from flask import Flask, render_template, request

# Custom Modules
from google_books_hf import process_list

# Retreive Google API key from environment


def create_app():
Expand All @@ -16,14 +27,26 @@ def create_app():
# to api documentation
def root():
return render_template('base.html',page_name='home')
@app.route('/search/<search_term>')

@app.route('/search')
# the input is going to be a string
# output will be a list of books from the google api
# formatting of the output should be in OUT_LIST format
def search():
return render_template('base.html',page_name='search')
def search(search_term):
GOOGLE_KEY = os.environ['GOOGLE_KEY']
response = requests.get('https://www.googleapis.com/books/v1/volumes?q='
+ search_term
+ '&key='
+ GOOGLE_KEY)
result = json.loads(response.text)

relevant_details=['id','title','authors','publisher',
'publishedDate','description','industryIdentifiers',
'pageCount','categories','thumbnail','smallThumbnail',
'language','webReaderLink','textSnippet','isEbook']

output = process_list(result['items'],relevant_details)
return jsonify(output)

@app.route('/subject_list')
# input will be subject heading (this should be a valid value)
Expand Down
Loading

0 comments on commit ad19696

Please sign in to comment.