Last active
April 21, 2020 12:55
-
-
Save jmasonherr/6301914 to your computer and use it in GitHub Desktop.
Upload a photo to App Engine's Image service from a URL of an image elsewhere on the internet. Integrates App Engine's images service with InkPicker, so we can use their upload and store the actual image in our server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Requires poster https://pypi.python.org/pypi/poster/ | |
# Requires webapp2 on App Engine for demo | |
# Example usage: | |
# import requests | |
# 'http://upload.wikimedia.org/math/4/7/9/479d9d21b183eb546b771447fcf69ddf.png' | |
# response = requests.post('http://myapp.appspot.com/i/post_from_url', {'url': wikipediaimg}) | |
import json | |
import urllib2 | |
# Blobstore handlers for dealing with POST request | |
import webapp2 | |
from google.appengine.api import urlfetch | |
from google.appengine.api import images | |
from google.appengine.ext import blobstore | |
from google.appengine.ext.webapp import blobstore_handlers | |
# Poster makes the multipart request easy | |
from poster.encode import multipart_encode, MultipartParam | |
from poster.streaminghttp import register_openers | |
# URLS are routed on this page for demonstration, not true in production | |
from webapp2 import Route, WSGIApplication | |
from imagehost_settings import app_config, IMAGE_UPLOAD_LOCATION | |
# App Engine doesn't allow writing to a file system, | |
# which makes uploading photos a little trickier | |
# This code allows a post like this: | |
#{'url' : 'http://upload.wikimedia.org/math/4/7/9/479d9d21b183eb546b771447fcf69ddf.png'} | |
# to save the actual image in the images service | |
# Wherever your server expects to get multipart/form requests | |
IMAGE_UPLOAD_LOCATION = '/i/upload' | |
class PostFromURLHandler(webapp2.RequestHandler): | |
def post(self): | |
""" post an image url from somewhere else on the internet, get it posted to our own servers""" | |
# get url of image we want to save on our servers | |
image_url = self.request.get('url') | |
upload_url = blobstore.create_upload_url(IMAGE_UPLOAD_LOCATION) | |
# Need filetype and name for POST to work | |
filetype = 'image/%s' % image_url.split('.')[-1] | |
filename = image_url.split('/')[-1] | |
raw_img = urlfetch.fetch(image_url).content | |
multipart_param = MultipartParam('image', raw_img, filename=filename, filetype=filetype) | |
datagen, headers = multipart_encode([multipart_param]) | |
# Post the image | |
response = urlfetch.fetch(url=upload_url, payload="".join(datagen), method=urlfetch.POST, headers=headers) | |
# Return whatever your image handlers normally return if uploading something | |
# from a user's filesystem | |
self.response.headers['Content-Type'] = 'application/json' | |
self.response.out.write(response.content) | |
class ImageUploader(blobstore_handlers.BlobstoreUploadHandler): | |
""" | |
Handles uploads for images, grabbing blob info from multipart handler and doing whatever | |
with it (like saving its info to a model) | |
/i/url leads to here | |
""" | |
def post(self): | |
attribute = self.request.get('attribute') | |
fieldname = self.request.get('fieldname') or 'image' | |
image_info = [] | |
#logging.info('looking at fieldname %s' % fieldname) | |
for blobInfo in self.get_uploads(): | |
blobkey = blobInfo.key() | |
# Get serving url for image | |
image_url = images.get_serving_url(blobkey) | |
# get image properties | |
data = blobstore.fetch_data(blobkey, 0, 50000) | |
actualImg = images.Image(image_data=data) | |
#logging.info(actualImg) | |
height = actualImg.height | |
width = actualImg.width | |
# Save your image somehow... | |
# Add to array of successes | |
image_info.append({'url': image_url, | |
'height': height, | |
'width': width, | |
}) | |
# Return its info | |
self.response.headers['Content-Type'] = 'application/json' | |
self.response.out.write(json.dumps(image_info)) | |
rtes = [ | |
# image handlers | |
Route(IMAGE_UPLOAD_LOCATION, handler='imagehost.api.ImageUploader'), | |
Route(r'/i/post_from_url', handler='imagehost.api.PostFromURLHandler'), | |
] | |
application = WSGIApplication(rtes, config=app_config, debug=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment