Running a Python NDB App with Firestore Emulator in Datastore Mode
If you want to test a Google Cloud NDB app locally before pushing it to Cloud Run, you can wire it up with the Firestore emulator (in Datastore mode). Here’s a minimal setup.
Project Layout
app/
main.py
models.py
templates/index.html
requirements.txt
Makefile
Requirements
# requirements.txt
Flask==3.0.3
google-cloud-ndb==2.2.2
Models
# models.py
from google.cloud import ndb
class Counter(ndb.Model):
value = ndb.IntegerProperty(default=0)
App
# main.py
import os
from flask import Flask, render_template
from google.cloud import ndb
from models import Counter
app = Flask(__name__)
def get_client():
return ndb.Client(project=os.getenv("DATASTORE_PROJECT_ID", "demo-project"))
@app.route("/")
def index():
client = get_client()
with client.context():
counter = Counter.get_by_id("main") or Counter(id="main", value=0)
counter.value += 1
counter.put()
return render_template("index.html", count=counter.value)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8081, debug=True)
HTML Template
<!-- templates/index.html -->
<!doctype html>
<html>
<body>
<h1>Counter Value: {{ count }}</h1>
</body>
</html>
Makefile
PROJECT_ID=demo-project
run_emulator:
gcloud beta emulators firestore start \
--host-port=localhost:8082 \
--project=$(PROJECT_ID) \
--use-firestore-in-datastore-mode
run_app:
DATASTORE_PROJECT_ID=$(PROJECT_ID) \
DATASTORE_EMULATOR_HOST=localhost:8082 \
python3 main.py
Running the App
- Start the emulator:
make run_emulator
- In another terminal, run the app:
make run_app
- Visit http://localhost:8081. Each refresh increments the counter.
That’s it: a tiny Flask + NDB app, backed by the Firestore emulator in Datastore mode. Ready to push to Cloud Run later.