I've been migrating from Python 2.7 webapp2 to Python 3 Flask.
I'm currently stuck on trying to get the Python 3 runtime to mimic the Python 2 runtime behaviour when it comes to accessing Google Cloud Storage.
The old Python 2.7 runtime automatically used the local Cloud Storage emulator, but I can only get the Python 3 runtime to save to the cloud based Google Cloud Storage.
This means anything running on local dev that uses the blob key of a Cloud Storage object (e.g. the Images API), is failing.
I tried auto-authenticating with Cloud Storage like this:
from google.cloud import storage
from google.auth.app_engine import Credentials
credentials = Credentials()
client = storage.Client(credentials=credentials)
then any call (e.g. stat()) to Cloud Storage would timeout.
So to get it working I download a JSON credential file and used this instead:
from google.cloud import storage
from google.auth.app_engine import Credentials
from google.oauth2 import service_account
credentials = service_account.Credentials.from_service_account_file('/file/path.json')
client = storage.Client(credentials=credentials)
I suspect this is the culprit (using JSON file credentials instead of auto-auth), but not sure how to get auto-auth working without timing out.
Any ideas?
from google.cloud import storage
means you're using Cloud Storage (calling it via the Python Cloud Storage Client Library). Therefore, it will connect to 'production' i.e. 'Cloud' and not your local machine unless you've started an emulator (like Cloud Datastore Emulator for Datastore). However, Cloud Storage doesn't have such an emulator (I think there are 3rd parties but none from Google).Even running with
dev_appserver.py
won't solve your problem because per Google documentation (Python 3, Python 2)In Python 2, you were probably doing something like
import cloudstorage
and that seemed to have been specifically designed for GAE and it had an emulator (see this). Cloud Storage is meant to work for different Apps and not just GAEUpdate - Adding working code (tested; it works)
Notes
Code supports uploading multiple images but it returns after processing the first image. You can modify the code to add processed images to a list and then return the list
If you run this on dev env, the image will be uploaded and you'll get a serving image url but it will give you a 404 if you try to open it in a browser because the baseurl is your localhost but the image is actually on cloud
I also had to include
google-cloud-datastore
inrequirements.txt
because I noticed that Images.getBaseURI errored out without it. Don't know if this will be required in production