<jupyter_start><jupyter_text>Food2Fork API www.food2fork.com/about/api<jupyter_code># API access
import requests
import urllib2
from urllib import urlencode
import json
from bs4 import BeautifulSoup

# Plotting
from matplotlib import pyplot as plt

# Parsing ingredient lists
import re
import nltk
from fractions import Fraction
from ingredient_parser import parse # https://pypi.python.org/pypi/ingredient-parser/1.0.1
%matplotlib inline<jupyter_output><empty_output><jupyter_text>API credentials<jupyter_code>def loadCredentials():
    filename = 'secrets.txt'
    for line in open(filename).readlines():
        if "API" in line:    
            api_key = line.split(": ")[1].translate(None,'\n')
        
    return api_key
# Load the API Key
_API_KEY = loadCredentials()

# Food2Fork links
_URL_API = "http://food2fork.com/api/"
_URL_SEARCH = _URL_API + 'search?'
_URL_GET    = _URL_API + 'get?'
_HEADER = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64)'}<jupyter_output><empty_output><jupyter_text>Search the Food2Fork API<jupyter_code>def search(query, page=1, count=1):   
    """Return a list of recipes from the Food2Fork.com database"""
    
    assert(0 < count <= 30), 'max 30 results per call, min 1' #https://github.com/davebshow/food2forkclient/
        
    # Format the request URL
    query_params = {"key":_API_KEY,"q":query, "page":page, "count":count}            
    api_request = _URL_SEARCH + urlencode(query_params)    

    # Make the request
    request  = urllib2.Request(api_request, headers=_HEADER)
    response = urllib2.urlopen(request)
    raw = response.read()
    json_obj = json.loads(raw)['recipes']
    
    if len(json_obj)==1:    
        return json_obj[0]
    else:
        return json_obj
# Search for cookie recipes
recipes = search('Chocolate chip cookies',count=5)
print(recipes[0]['image_url'])
recipes[0]<jupyter_output>http://static.food2fork.com/508714d505.jpg<jupyter_text>Request a specific recipe from the API<jupyter_code>def getRecipe(recipe_id):
    """Return the recipe specified by *recipe_id* from Food2Fork's database"""

    # Format the request URL
    api_request = _URL_GET + urlencode({"key":_API_KEY, "rId":recipe_id})
    
    # Make the request
    request  = urllib2.Request(api_request, headers=_HEADER)
    response = urllib2.urlopen(request)
    raw = response.read()
    json_obj = json.loads(raw)  
    
    return json_obj['recipe']<jupyter_output><empty_output><jupyter_text>Scrape ingredients from a Food2Fork.com page<jupyter_code>def getIngredients(json_obj):
    r = getRecipe(json_obj['recipe_id'])
    return [i.strip('\n').encode('ascii', 'ignore').lower() for i in r['ingredients']]<jupyter_output><empty_output><jupyter_text>Parse ingredient amounts using reg exp and NLTK   Attempt to parse with regular expressions<jupyter_code>class Ingredient(object):
    
    def __init__(self, name, amount='', units='', description=''):
        self._name = name # e.g. butter, sugar, etc. (this needs a better variable name than "name")        
        self._amount = amount # How many of units?
        self._units = units   # Measurement units (e.g. cup, tablespoon, pound, etc.)
        self._description = description # e.g. softened, blackened, etc.
                
    @property
    def name(self): # e.g. butter, chocolate chips, ground beef
        return self._name

    @property
    def units(self): # e.g. cups, teaspoons, oz
        return self._units
    
    @property
    def amount(self): # e.g. 1, 2, 1 1/2, 3/4
        return self._amount    
    
    @property
    def description(self): # e.g. softened, lightly-packed
        return self._description
    
    def __repr__(self):        
        return repr((self.amount, self.units, self.name))
# num_words = ['zero','one','two','three','four','five','six','seven','eight','nine',
#            'ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen',
#            'seventeen','eighteen','nineteen','twenty']
# NUMBERS = dict(zip(num_words,range(0,len(num_words))))
def parseIngredients(ingredients):
    p = [parse(ingrd) for ingrd in ingredients]
    num_ingredients = len(p)

    # Use RegEx to get ingredient amount from parsed list
    expr = r'\d*\s*\d*((/|.)\d+)?'
    matches = [re.search(expr,ingrd['measure']) for ingrd in p]
    amounts = [match.group().strip() for match in matches]

    # Convert amounts to float
    amounts = [float(sum(Fraction(s) for s in a.split())) for a in amounts]

    # Get measurement unit from the RegEx matches
    units = [i['measure'][m.end():].strip() for i,m in zip(p,matches)]

    # Get parts of speech using NLTK
    pos = [nltk.pos_tag(nltk.word_tokenize(ingrd['name'])) for ingrd in p]

    # Ingredient names
    tags = ['NN','NNS','VBG'] #JJ also?
    names = [' '.join([part[0] for part in parts if part[1] in tags]) for parts in pos]

    # Ingredient descriptions
    tags = ['JJ','VBD']
    descriptions = [' '.join([part[0] for part in parts if part[1] in tags]) for parts in pos]
                    
    return [Ingredient(n,a,u,d) for a,u,n,d in zip(amounts,units,names,descriptions)]
search_result = search("Chocolate chip cookies",count=5)
ingredients = getIngredients(getRecipe(search_result[0]['recipe_id']))
ingredients
parsed = parseIngredients(ingredients)
parsed
recipe = dict(zip([p.name for p in parsed],[p.amount for p in parsed]))
recipe
plt.plot(recipe['butter'],recipe['sugar'],'ro')
plt.show()
search_result = search("soup",count=5)
ingredients = getIngredients(getRecipe(search_result[0]['recipe_id']))
ingredients<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13502865329512895, 'fraction_numerical': 0.01181948424068768, 'mean_word_length': 3.8480902777777777, 'pattern_counts': {'":': 7, '<': 26, '<?xml version=': 0, '>': 24, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '80796', 'license': 'MIT', 'n_tokens_mistral': 1925, 'n_tokens_neox': 1861, 'n_words': 452, 'path': 'RecipesAPI.ipynb', 'repo_name': 'johnwmillr/RecipesAPI', 'size': '5584'}