mlarocca / app.yaml secret
Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist
View app.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
application: pweb-14
version: 1
runtime: python27
api_version: 1
threadsafe: yes
 
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
 
- url: /
static_files: static/index.html
upload: /
 
- url: /json.*
script: main.app
 
- url: /videos.*
script: videos.app
 
libraries:
- name: webapp2
version: "2.5.2"
View app.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import webapp2
import json
from apiclient.discovery import build
from apiclient.errors import HttpError
 
# Set DEVELOPER_KEY to the API key value from the APIs & auth > Registered apps
# tab of
# https://cloud.google.com/console
# Please ensure that you have enabled the YouTube Data API for your project.
DEVELOPER_KEY = "REPLACE_ME"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
 
def youtube_search(query, max_results=20):
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY)
 
# Call the search.list method to retrieve results matching the specified
# query term.
search_response = youtube.search().list(
q=query,
part="id,snippet",
maxResults=max_results,
type="video"
).execute()
 
#extract only a few 'interesting' fields from the data
result_transform = lambda search_result: {
'id': search_result['id']['videoId'],
'title': search_result['snippet']['title'],
'thumbnail': search_result['snippet']['thumbnails']['default']['url'],
'date': search_result['snippet']['publishedAt']
}
# Filter results to retaun only matching videos, and filter out channels and playlists.
return map(result_transform, search_response.get("items", []))
 
 
class MainHandler(webapp2.RequestHandler):
def get(self):
self.error(404) #just an example to show you how to return an error
 
class JsonHandler(webapp2.RequestHandler):
def get(self):
 
query = self.request.get('query', default_value=None)
 
if query and len(query) >= 2:
try:
query_result = youtube_search(query)
except HttpError, e:
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("An HTTP error %d occurred:\n%s" % (e.resp.status, e.content))
return
else:
query_result = []
 
self.response.headers['Content-Type'] = 'application/json'
self.response.out.write(json.dumps(query_result))
 
 
app = webapp2.WSGIApplication([
('/', MainHandler),
('/json/?', JsonHandler)
], debug=True)
View app.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import webapp2
import json
from apiclient.discovery import build
from apiclient.errors import HttpError
 
# Set DEVELOPER_KEY to the API key value from the APIs & auth > Registered apps
# tab of
# https://cloud.google.com/console
# Please ensure that you have enabled the YouTube Data API for your project.
DEVELOPER_KEY = "REPLACE_ME"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
YOUTUBE_MAX_RESULTS_PER_PAGE = 50
 
class VideoSearchHandler(webapp2.RequestHandler):
 
#list all the possible valid values for the order
__VALID_ORDER_CRITERIA = set(['date', 'rating', 'relevance', 'title', 'videoCount', 'viewCount'])
__DEFAULT_SORTING_CRITERION = 'relevance'
def __validate_order(self, criterion):
""" Validate the criterion passed, by verifying it is among the ones acceptable by the API
"""
return criterion if criterion in VideoSearchHandler.__VALID_ORDER_CRITERIA else VideoSearchHandler.__DEFAULT_SORTING_CRITERION
 
def __extract_positive_int(self, param_name, default_value):
try:
v = int(self.request.get(param_name, default_value=default_value))
if v <= 0:
return default_value
else:
return v
except TypeError:
return default_value
 
def __extract_params(self):
return {
'first_result': self.__extract_positive_int('first_result', 1),
'max_results': self.__extract_positive_int('max_results', None),
'order': self.__validate_order(self.request.get('order', default_value=None))
}
 
def __search_youtube_videos(self, keywords, params, related_id, regionCode):
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY)
 
# Filter results to retaun only matching videos, and filter out channels and playlists.
result_transform = lambda search_result: {
'id': search_result['id']['videoId'],
'title': search_result['snippet']['title'],
'thumbnail': search_result['snippet']['thumbnails']['default'],
'date': search_result['snippet']['publishedAt']
}
 
#prepare the parameters for the list method
search_params = {
'q':keywords,
'part':"id,snippet",
'type':'video'
}
 
if not related_id is None:
search_params['relatedToVideoId'] = related_id
if not regionCode is None:
search_params['regionCode'] = regionCode
if not params['order'] is None:
search_params['order'] = params['order']
 
first_result = params['first_result'] if 'first_result' in params else 1
#To leave things simple, it checks that the first and last result fall in the first results page
if first_result >= YOUTUBE_MAX_RESULTS_PER_PAGE:
raise HttpError("Invalid parameter: first_result must be lower than %d" % YOUTUBE_MAX_RESULTS_PER_PAGE, 403)
 
if not params['max_results'] is None:
max_result = first_result + params['max_results']
search_params['maxResults'] = max_result
 
#To leave things simple, it checks that the first and last result fall in the first results page
if max_result > YOUTUBE_MAX_RESULTS_PER_PAGE:
max_result = YOUTUBE_MAX_RESULTS_PER_PAGE
 
search_params['maxResults'] = max_result
 
# Call the search.list method to retrieve results matching the keywords.
search_response = youtube.search().list(
**search_params #unpack the dictionary to a list of named parameters
).execute()
 
return map(result_transform, search_response.get("items", [])[first_result:search_response['pageInfo']['totalResults']])
 
def search_videos(self, keywords, related_id=None, regionCode=None):
params = self.__extract_params()
self.return_results(self.__search_youtube_videos(keywords, params=params, related_id=related_id, regionCode=regionCode))
 
def return_results(self, results):
self.response.headers['Content-Type'] = 'application/json'
self.response.out.write(json.dumps(results))
 
class SimpleVideoSearchHandler(VideoSearchHandler):
def get(self, keywords):
self.search_videos(keywords)
 
class RelatedVideoSearchHandler(VideoSearchHandler):
def get(self, keywords, related_id):
self.search_videos(keywords, related_id=related_id)
 
class VideoSearchHandlerWithRegion(VideoSearchHandler):
def get(self, keywords, regionCode):
self.search_videos(keywords, regionCode=regionCode.upper())
 
app = webapp2.WSGIApplication([
('/videos/([^/]+)/?', SimpleVideoSearchHandler),
('/videos/([^/]+)/countries/([^/]+)/?', VideoSearchHandlerWithRegion),
('/videos/([^/]+)/related/([^/]+)/?', RelatedVideoSearchHandler)
], debug=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.