Skip to content

Instantly share code, notes, and snippets.

@jmasonherr
Last active April 21, 2020 12:55
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmasonherr/6301914 to your computer and use it in GitHub Desktop.
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
# 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