11
votes

I've been reading between the lines and trying to interface dev_appserver.py with the new 'non-legacy' google cloud datastore emulator.

My main motivation is to integrate my appengine projects with my google cloud dataflow pipeline while I am developing on my local machine.

This is the procedure to setup the integration, as far as I understand:

  • Install the googledatastore library with pip (you may need to force an upgrade of six with easy_install particularly if you are using system python El Capitan)
  • Using the google cloud sdk tools run the google cloud datastore emulator:

    gcloud beta emulators datastore start --no-legacy
    
  • In the terminal where dev_appserver will run the following command to set datastore environment variables:

    $(gcloud beta emulators datastore env-init --no-legacy)
    
  • If the project id in app.yaml does not match the currently select project id in the gcloud tools set the following environment variable in the same shell:

    export DATASTORE_USE_PROJECT_ID_AS_APP_ID=true
    
  • Run dev_appserver.py and navigate to http://localhost:8000/datastore which should let you navigate the emulator's datastore data.

However this does not work so smoothly when I navigate to the url I get:

BadArgumentError: Could not import googledatastore.
This library must be installed with version >= 4.0.0.b1 to use the Cloud Datastore 
API.

This is strange because if I open a python shell and run import googledatastore no error occurs.

If I dig a bit deeper and instrument the import code in dev_appserver and log the error here I get the following traceback:

Traceback (most recent call last):
  File "/usr/local/google-cloud-sdk/platform/google_appengine/google/appengine/datastore/datastore_pbs.py", line 52, in <module>
    import googledatastore
  File "/Library/Python/2.7/site-packages/googledatastore/__init__.py", line 21, in <module>
    from . import helper
  File "/Library/Python/2.7/site-packages/googledatastore/helper.py", line 25, in <module>
    from google.datastore.v1beta3 import entity_pb2
ImportError: No module named datastore.v1beta3 

I also have no issue importing google.datastore.v1beta3 in a regular python shell.

Even stranger if I run PYTHONINSPECT=x dev_appserver.py app.yaml and drop out into the shell executing these imports runs without error. Perhaps there is something odd going on with the python path while dev_appserver.py is starting?

Can anybody tell me how to get this feature working?

UPDATE: I reproduced this problem on ubuntu 14.04 (system python 2.7.6, pip 8.1.2 via easy_install, gcloud-sdk 118.0.0, app-engine-python 1.9.38) as well as OS X (gcloud sdk 114.0.0, app-engine-python 1.9.38, system python 2.7.10).

3
FWIW, GAE SDK 1.9.38 is affected by a bug causing import errors similar to yours, see stackoverflow.com/questions/37755195/…. I'd suggest trying with 1.9.40 (latest now) which has the fix.Dan Cornilescu
@zenlambda did you ever get this to work?ThomasD
This is still occurring as of this post. I've posted an issue on the Public Issue Tracker for App Engine, and folks can follow there for a solution.Nick
I get the same error. Have you found any solution?Sefran2

3 Answers

5
votes

Heads up folks,

Using google cloud datastore emulator with dev_appserver is now available! (link)

Update Google Cloud SDK, then run dev_appserver with '----support_datastore_emulator'.

This feature is in Beta, welcome to try it! We are actively collecting feedback.

3
votes

Actually gcloud datastore emulator and dev_appserver points to two different endpoints. the localhost:8000 is the default dev_appserver admin console, while the datastore emulator have a different console url which could be found in print outs when it starts.

I assume the admin console you are accessing belongs to dev_appserver, then the issue should be within dev_appserver. Could you attach the code snippet(if there is any) using datastore api in dev_appserver? BTW it should be gcloud.datastore instead of appengine.ext.(n)db talking to gcloud datastore-emulator.

Also, I'm curious what would happen if you do not start datastore-emulator with '--no-legacy', or even do not start datastore-emulator but just start dev_appserver?

3
votes

We recently ran into this same issue. One thing to look at is the output of the command:

(gcloud beta emulators datastore env-init --no-legacy)

The problem we had was that when we ran the emulator the emulator was choosing say port 8607 but the env-init method was returning a different port 8328.

So, what I would recommend is to start the emulator and see what port it is running on:

[datastore] Aug 04, 2016 3:50:50 PM com.google.appengine.tools.development.AbstractModule startup
[datastore] INFO: Module instance default is running at http://localhost:8607/
[datastore] Aug 04, 2016 3:50:50 PM com.google.appengine.tools.development.AbstractModule startup
[datastore] INFO: The admin console is running at http://localhost:8607/_ah/admin

In this case 8607 and then fire off the env-init method to get the syntax but validate the port. In our case with the above server running the env-init returns 8328

$ (gcloud beta emulators datastore env-init)
export DATASTORE_DATASET=my-app
export DATASTORE_EMULATOR_HOST_PATH=localhost:8328/datastore
export DATASTORE_EMULATOR_HOST=localhost:8328
export DATASTORE_HOST=http://localhost:8328
export DATASTORE_PROJECT_ID=my-app

So change this to the correct port:

export DATASTORE_DATASET=my-app
export DATASTORE_EMULATOR_HOST_PATH=localhost:8607/datastore
export DATASTORE_EMULATOR_HOST=localhost:8607
export DATASTORE_HOST=http://localhost:8607
export DATASTORE_PROJECT_ID=my-app

Then use this where your project is running and you should be good to go. This is what fixed it for us. Hope that helps!