In [1]:
from yelp.client import Client
from yelp.oauth1_authenticator import Oauth1Authenticator
import io
import json
with io.open('config_yelp.json') as cred:
creds = json.load(cred)
auth = Oauth1Authenticator(**creds)
client = Client(auth)
biz = client.get_business('yelp-san-francisco')
In [8]:
biz = client.get_business('yolk-chicago-8')
biz.business.categories
Out[8]:
In [9]:
biz.business.eat24_url
In [17]:
biz.business.reviews[0].excerpt
Out[17]:
In [18]:
biz.business.ho
Out[18]:
In [ ]:
"""Functions to make API call to Yelp for restaurants in a city"""
from model import City, Restaurant
from model import db
from sqlalchemy.orm.exc import NoResultFound
from yelp.client import Client
from yelp.oauth1_authenticator import Oauth1Authenticator
import io
import json
# def get_city_id(city):
# """Get the city id from database. Otherwise, add city to database and get the city id."""
# try:
# existing_city = db.session.query(City).filter(City.name == city).one()
# except NoResultFound:
# new_city = City(name=city)
# db.session.add(new_city)
# db.session.commit()
# return new_city.city_id
# return existing_city.city_id
# Resource for how to offset Yelp API results from http://www.mfumagalli.com/wp/portfolio/nycbars/
def get_restaurants(city, offset):
"""
Returns API response from Yelp API call to get restaurants for a city, with the results offset.
Note that Yelp only returns 20 results each time, which is why we need to offset if we want
the next Nth results.
"""
# Read Yelp API keys
with io.open('config_yelp.json') as cred:
creds = json.load(cred)
auth = Oauth1Authenticator(**creds)
client = Client(auth)
# Set term as restaurant to get restaurants for results
# Need to pass in offset, so Yelp knows how much to offset by
params = {
'term': 'restaurant',
'offset': offset
}
return client.search(city, **params)
def load_restaurants(city):
"""Get all restaurants for a city from Yelp and load restaurants into database."""
# Get city id, as city id is a required parameter when adding a restaurant to the database
city_id = get_city_id(city)
# Start offset at 0 to return the first 20 results from Yelp API request
offset = 0
# Get total number of restaurants for this city
total_results = get_restaurants(city, offset).total
# Get all restaurants for a city and load each restaurant into the database
# Note: Yelp has a limitation of 1000 for accessible results, so get total results
# if less than 1000 or get only 1000 results back even if there should be more
while 1000 > offset < total_results:
# API response returns a SearchResponse object with accessible attributes
# response.businesses returns a list of business objects with further attributes
for business in get_restaurants(city, offset).businesses:
restaurant = Restaurant(city_id=city_id,
name=business.name,
address=" ".join(business.location.display_address),
phone=business.display_phone,
image_url=business.image_url,
latitude=business.location.coordinate.latitude,
longitude=business.location.coordinate.longitude)
db.session.add(restaurant)
# Yelp returns only 20 results each time, so need to offset by 20 while iterating
offset += 20
db.session.commit()
In [3]:
"""Models and database functions."""
import datetime
# from sqlalchemy_searchable import make_searchable
# from sqlalchemy_utils.types import TSVectorType
# This is the connection to the PostgreSQL database; we're getting this through
# the Flask-SQLAlchemy helper library. On this, we can find the `session`
# object, where we do most of our interactions (like committing, etc.)
# db = SQLAlchemy()
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
Base = declarative_base()
# make_searchable()
##############################################################################
# Model definitions
# class User(db.Model):
# """User of website."""
# __tablename__ = "users"
# user_id = db.Column(db.Integer, autoincrement=True, primary_key=True)
# city_id = db.Column(db.Integer, db.ForeignKey('cities.city_id'), nullable=False)
# email = db.Column(db.String(100), unique=True, nullable=False)
# password = db.Column(db.String(100), nullable=False)
# first_name = db.Column(db.String(100), nullable=False)
# last_name = db.Column(db.String(100), nullable=False)
# # Put name inside TSVectorType definition for it to be fulltext-indexed (searchable)
# search_vector = db.Column(TSVectorType('first_name', 'last_name'))
# city = db.relationship("City", backref=db.backref("users"))
# def __repr__(self):
# """Provide helpful representation when printed."""
# return "<User user_id=%s email=%s>" % (self.user_id,
# self.email)
class Restaurant(Base):
"""Restaurant on website."""
__tablename__ = "restaurants"
[u'is_claimed', u'rating', u'review_count', u'name', u'phone', u'url',
u'price', u'coordinates', u'hours', u'photos', u'image_url', u'categories',
u'display_phone', u'id', u'is_closed', u'location']
restaurant_id = Column(Integer, autoincrement=True, primary_key=True)
yelp_id = db.Column(db.String(150), nullable=True)
yelp_rating = db.Column(db.Numeric, nullable=True)
yelp_review_count = db.Column(db.Integer, nullable=True)
name = db.Column(db.String(150), nullable=False)
phone = db.Column(db.String(20), nullable=True)
yelp_url = db.Column(db.String(200), nullable=True)
yelp_price_level = db.Column(db.String(10), nullable=True)
latitude = db.Column(db.Numeric, nullable=True)
longitude = db.Column(db.Numeric, nullable=True)
hours_type = db.Column(db.String(20), nullable=True)
is_open_now = db.Column(db.Boolean(), nullable=True)
hour_start_monday = db.Column(db.String(20), nullable=True)
hour_end_monday = db.Column(db.String(20), nullable=True)
hour_start_tuesday = db.Column(db.String(20), nullable=True)
hour_end_tuesday = db.Column(db.String(20), nullable=True)
hour_start_wednesday = db.Column(db.String(20), nullable=True)
hour_end_wednesday = db.Column(db.String(20), nullable=True)
hour_start_thursday = db.Column(db.String(20), nullable=True)
hour_end_thursday = db.Column(db.String(20), nullable=True)
hour_start_friday = db.Column(db.String(20), nullable=True)
hour_end_friday = db.Column(db.String(20), nullable=True)
hour_start_saturday = db.Column(db.String(20), nullable=True)
hour_end_saturday = db.Column(db.String(20), nullable=True)
hour_start_sunday = db.Column(db.String(20), nullable=True)
hour_end_sunday = db.Column(db.String(20), nullable=True)
is_closed = db.Column(db.Boolean(), nullable=True)
categories = db.Column(db.String(200), nullable=True)
display_phone = db.Column(db.String(50), nullable=True)
location = db.Column(db.String(400), nullable=True)
# Latitude and Longitude need to be Numeric, not Integer to have decimal places
# Put restaurant name and address inside definition of TSVectorType to be fulltext-indexed (searchable)
# city = db.relationship("City", backref=db.backref("restaurants"))
# categories = db.relationship("Category", secondary="restaurantcategories", backref="restaurants")
# users = db.relationship("User", secondary="visits", backref="restaurants")
def __repr__(self):
"""Provide helpful representation when printed."""
return "<Restaurant restaurant_id=%s name=%s>" % (self.restaurant_id,
self.name)
# class Visit(db.Model):
# """User's visited/saved restaurant on Breadcrumbs website.
# Association table between User and Restaurant.
# """
# __tablename__ = "visits"
# visit_id = db.Column(db.Integer, autoincrement=True, primary_key=True)
# user_id = db.Column(db.Integer, db.ForeignKey('users.user_id'), nullable=False)
# restaurant_id = db.Column(db.Integer, db.ForeignKey('restaurants.restaurant_id'), nullable=False)
# user = db.relationship("User", backref=db.backref("visits"))
# restaurant = db.relationship("Restaurant", backref=db.backref("visits"))
# def __repr__(self):
# """Provide helpful representation when printed."""
# return "<Visit visit_id=%s restaurant_id=%s>" % (self.visit_id,
# self.restaurant_id)
# class City(db.Model):
# """City where the restaurant is in."""
# __tablename__ = "cities"
# city_id = db.Column(db.Integer, autoincrement=True, primary_key=True)
# name = db.Column(db.String(100), nullable=False)
# # Set default for timestamp of current time at UTC time zone
# updated_At = db.Column(db.DateTime, default=datetime.datetime.utcnow)
# def __repr__(self):
# """Provide helpful representation when printed."""
# return "<City city_id=%s name=%s>" % (self.city_id,
# self.name)
# class Category(db.Model):
# """Category of the restaurant."""
# __tablename__ = "categories"
# category_id = db.Column(db.Integer, autoincrement=True, primary_key=True)
# name = db.Column(db.String(100), unique=True, nullable=False)
# def __repr__(self):
# """Provide helpful representation when printed."""
# return "<Category category_id=%s name=%s>" % (self.category_id,
# self.name)
# class RestaurantCategory(db.Model):
# """Association table linking Restaurant and Category to manage the M2M relationship."""
# __tablename__ = "restaurantcategories"
# restcat_id = db.Column(db.Integer, autoincrement=True, primary_key=True)
# restaurant_id = db.Column(db.Integer, db.ForeignKey('restaurants.restaurant_id'), nullable=False)
# category_id = db.Column(db.Integer, db.ForeignKey('categories.category_id'), nullable=False)
# def __repr__(self):
# """Provide helpful representation when printed."""
# return "<RestaurantCategory restcat_id=%s restaurant_id=%s category_id=%s>" % (self.restcat_id,
# self.restaurant_id,
# self.category_id)
# class Image(db.Model):
# """Image uploaded by user for each restaurant visit."""
# __tablename__ = "images"
# image_id = db.Column(db.Integer, autoincrement=True, primary_key=True)
# visit_id = db.Column(db.Integer, db.ForeignKey('visits.visit_id'), nullable=False)
# url = db.Column(db.String(200), nullable=False)
# uploaded_At = db.Column(db.DateTime, default=datetime.datetime.utcnow)
# taken_At = db.Column(db.DateTime, nullable=True)
# rating = db.Column(db.String(100), nullable=True)
# visit = db.relationship("Visit", backref=db.backref("images"))
# def __repr__(self):
# """Provide helpful representation when printed."""
# return "<Image image_id=%s visit_id=%s>" % (self.image_id,
# self.visit_id)
# class Connection(db.Model):
# """Connection between two users to establish a friendship and can see each other's info."""
# __tablename__ = "connections"
# connection_id = db.Column(db.Integer, autoincrement=True, primary_key=True)
# user_a_id = db.Column(db.Integer, db.ForeignKey('users.user_id'), nullable=False)
# user_b_id = db.Column(db.Integer, db.ForeignKey('users.user_id'), nullable=False)
# status = db.Column(db.String(100), nullable=False)
# # When both columns have a relationship with the same table, need to specify how
# # to handle multiple join paths in the square brackets of foreign_keys per below
# user_a = db.relationship("User", foreign_keys=[user_a_id], backref=db.backref("sent_connections"))
# user_b = db.relationship("User", foreign_keys=[user_b_id], backref=db.backref("received_connections"))
# def __repr__(self):
# """Provide helpful representation when printed."""
# return "<Connection connection_id=%s user_a_id=%s user_b_id=%s status=%s>" % (self.connection_id,
# self.user_a_id,
# self.user_b_id,
# self.status)
##############################################################################
# Helper functions
# def connect_to_db(app, db_uri=None):
# """Connect the database to our Flask app."""
# # Configure to use our PostgreSQL database
# app.config['SQLALCHEMY_DATABASE_URI'] = db_uri or 'postgresql:///zoeshrm'
# app.config['SQLALCHEMY_ECHO'] = True
# db.app = app
# db.init_app(app)
def example_data():
"""Create some sample data for testing."""
# van = City(name="Vancouver")
chambar = Restaurant(name="Chambar",
address="568 Beatty St, Vancouver, BC V6B 2L3",
phone="(604) 879-7119",
latitude=49.2810018,
longitude=-123.1109668)
miku = Restaurant(name="Miku",
address="200 Granville St #70, Vancouver, BC V6C 1S4",
phone="(604) 568-3900",
latitude=49.2868017,
longitude=-123.1131884)
fable = Restaurant(name="Fable",
address="1944 W 4th Ave, Vancouver, BC V6J 1M7",
phone="(604) 732-1322",
latitude=49.2679389,
longitude=-123.2190482)
# ashley = User(city_id=1,
# email="ashley@test.com",
# password="ashley",
# first_name="Ashley",
# last_name="Test")
# bob = User(city_id=1,
# email="bob@test.com",
# password="bob",
# first_name="Bob",
# last_name="Test")
# cat = User(city_id=1,
# email="cat@test.com",
# password="cat",
# first_name="Cat",
# last_name="Test")
db.session.add_all([chambar, miku, fable])
db.session.commit()
if __name__ == "__main__":
# As a convenience, if we run this module interactively, it will leave
# you in a state of being able to work with the database directly.
# from server import app
# connect_to_db(app)
print "Connected to DB."
In [ ]: