Blog Logo

2-Oct-2025 ~ 2 min read

NDB GAE App on Localhost


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

  1. Start the emulator:
make run_emulator
  1. In another terminal, run the app:
make run_app
  1. 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.


End Result

Counter App Screenshot