Starten Sie den Cloud Datastore Emulator mit Docker-Compose und arbeiten Sie mit der Python-App

Hintergrund

Ich entschied mich für die Verwendung des Datenspeichers für den Dienst und versuchte und irrte, wie man in der Entwicklungsumgebung und in CI testet. : Denken: Da es im Vergleich zu AWS weniger Informationen gibt, habe ich diese zusammengefasst. : grinsend:

Der Punkt

--Erstellen Sie einen Container für die Kolben-App und den Cloud Datastore Emulator --Linker-Compose-Dienste

Verzeichnisaufbau

.
├── app
│   ├── Dockerfile
│   └── src
│       ├── main.py
│       └── requirements.txt
├── datastore
│   ├── Dockerfile
│   ├── entrypoint
│   └── import
│       ├── 2020-01-21.overall_export_metadata
│       ├── default_namespace
│       │   └── kind_test_data
│       │       ├── default_namespace_kind_test_data.export_metadata
│       │       └── output-0
│       └── run.sh
└──  docker-compose.yaml

Aufbau eines Cloud-Datenspeicher-Emulator-Containers

datastore/Dockerfile

Minimale Erstellung aus dem offiziellen SDK-Image. Erteilen Sie der Shell die Ausführungsberechtigung zum Starten des Emulators und der Shell zum Eingeben von Daten.

FROM google/cloud-sdk:alpine

RUN apk add --update --no-cache openjdk8-jre \
  && gcloud components install cloud-datastore-emulator beta --quiet

COPY . /datastore/

WORKDIR /datastore

RUN chmod +x ./entrypoint
RUN chmod +x ./import/run.sh

ENTRYPOINT ["./entrypoint"]

datastore/entrypoint

Selbst wenn "Docker-Compose Down" durchgeführt wird, werden die Daten im Verzeichnis "/ datastore / .data /" gespeichert, um die Daten zu pflegen.

Wenn Sie es ohne Optionen starten, können Sie nur innerhalb des Containers darauf zugreifen. Starten Sie es daher als "--host-port = 0.0.0.0: 8081". Gießen Sie es aus der Umgebungsvariablen zusammen mit dem Projektnamen.

#!/usr/bin/env bash

gcloud config set project ${DATASTORE_PROJECT_ID}

gcloud beta emulators datastore start \
  --data-dir=/datastore/.data \
  --host-port=${DATASTORE_LISTEN_ADDRESS}

Datenspeicher / import / run.sh für die Dateneingabe

Nach dem Starten des Servers können Sie die Daten importieren, indem Sie den Speicherpfad der ausgegebenen Daten auf den folgenden Endpunkt werfen.

export DATASTORE_PROJECT_ID

curl -X POST localhost:8081/v1/projects/${DATASTORE_PROJECT_ID}:import \
    -H 'Content-Type: application/json' \
    -d '{"input_url":"/datastore/import/2020-01-21.overall_export_metadata"}'

Datenspeicher / Import-Metadaten

Dieses Mal habe ich über die gcp-Konsole das gesamte Verzeichnis unter datastore / import auf gcs gespeichert. Die SDK-Daten können direkt generiert werden.

Python App Container Konstruktion

Erstellen Sie eine fließende App für das Beispiel.

app/Dockerfile

FROM python:3.7-slim-buster

ENV HOME /api/

ADD ./ ${HOME}

WORKDIR ${HOME}

RUN pip install --upgrade pip \
    && pip install --no-cache-dir -r ${HOME}src/requirements.txt

ENTRYPOINT ["python", "src/main.py"]

app/main.py

Ich denke, es ist etwas zu geeignet, aber ich habe einen Endpunkt erstellt, der nur Daten speichert und abruft. : Denken:

Die Authentifizierungsinformationen beißen die Dummy-Authentifizierung.

from flask import Flask, jsonify
from google.auth.credentials import AnonymousCredentials
from google.cloud import datastore
from os import getenv

client = datastore.Client(
    credentials=AnonymousCredentials(),
    project=getenv('PROJECT_ID')
)

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False


@app.route('/')
def index():
    key = client.key('EntityKind', 1234)
    entity = datastore.Entity(key=key)
    entity.update({
        'foo': u'bar'
    })
    client.put(entity)
    result = client.get(key)
    return jsonify(result)


if __name__ == '__main__':
    app.run(host='0.0.0.0')

app/requirements.txt

Flask==1.1.1
google-auth==1.6.2
google-cloud-datastore==1.8.0

docker-compose.yaml

Wenn Sie den Datenspeicherport auch auf der Hostseite öffnen, können Sie ihn mit den GUI-Tools anzeigen, was praktisch ist.

https://github.com/GabiAxel/google-cloud-gui

version: '3.7'

x-custom:
  gcp:
    - &gcp_project_id "dummy"

services:
  app:
    build: "./app/"
    volumes:
      - "./app/:/app/"
    environment:
      FLASK_APP: dev
      DATASTORE_HOST: "http://datastore:8081"
      DATASTORE_EMULATOR_HOST: "datastore:8081"
      PROJECT_ID: *gcp_project_id
      TZ: Asia/Tokyo
    ports:
      - "5000:5000"
    depends_on:
      - datastore
  datastore:
    build: "./datastore"
    volumes:
      - "./datastore/.data:/datastore/.data"
    environment:
      DATASTORE_PROJECT_ID: *gcp_project_id
      DATASTORE_LISTEN_ADDRESS: 0.0.0.0:8081
    ports:
      - "18081:8081"

Anlaufen

docker-compose up 

Wenn Sie mit Ihrem Browser oder Curl auf http: // localhost: 5000 zugreifen, sollte {"foo": "bar"} angezeigt werden.

Log

Sie können sehen, dass die Daten unten gespeichert sind

/datastore/.data/WEB-INF/appengine-generated/local_db.bin
datastore_1  | Updated property [core/project].
datastore_1  | WARNING: Reusing existing data in [/datastore/.data].
datastore_1  | Executing: /google-cloud-sdk/platform/cloud-datastore-emulator/cloud_datastore_emulator start --host=0.0.0.0 --port=8081 --store_on_disk=True --consistency=0.9 --allow_remote_shutdown /datastore/.data
app_1        |  * Serving Flask app "main" (lazy loading)
app_1        |  * Environment: production
app_1        |    WARNING: This is a development server. Do not use it in a production deployment.
app_1        |    Use a production WSGI server instead.
app_1        |  * Debug mode: off
app_1        |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
datastore_1  | [datastore] Jan 22, 2020 6:22:00 AM com.google.cloud.datastore.emulator.CloudDatastore$FakeDatastoreAction$9 apply
datastore_1  | [datastore] INFO: Provided --allow_remote_shutdown to start command which is no longer necessary.
datastore_1  | [datastore] Jan 22, 2020 6:22:01 AM com.google.cloud.datastore.emulator.impl.LocalDatastoreFileStub <init>
datastore_1  | [datastore] INFO: Local Datastore initialized:
datastore_1  | [datastore]      Type: High Replication
datastore_1  | [datastore]      Storage: /datastore/.data/WEB-INF/appengine-generated/local_db.bin
datastore_1  | [datastore] Jan 22, 2020 6:22:02 AM com.google.cloud.datastore.emulator.impl.LocalDatastoreFileStub load
datastore_1  | [datastore] INFO: Time to load datastore: 218 ms
datastore_1  | [datastore] API endpoint: http://0.0.0.0:8081
datastore_1  | [datastore] If you are using a library that supports the DATASTORE_EMULATOR_HOST environment variable, run:
datastore_1  | [datastore] 
datastore_1  | [datastore]   export DATASTORE_EMULATOR_HOST=0.0.0.0:8081
datastore_1  | [datastore] 
datastore_1  | [datastore] Dev App Server is now running.
datastore_1  | [datastore] 
datastore_1  | [datastore] The previous line was printed for backwards compatibility only.
datastore_1  | [datastore] If your tests rely on it to confirm emulator startup,
datastore_1  | [datastore] please migrate to the emulator health check endpoint (/). Thank you!
datastore_1  | [datastore] The health check endpoint for this emulator instance is http://0.0.0.0:8081/Jan 22, 2020 6:22:11 AM io.gapi.emulators.grpc.GrpcServer$3 operationComplete
datastore_1  | [datastore] INFO: Adding handler(s) to newly registered Channel.
datastore_1  | [datastore] Jan 22, 2020 6:22:11 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
datastore_1  | [datastore] INFO: Detected HTTP/2 connection.

Dateneingabe

Sie können Dump-Daten auch importieren, indem Sie eine Anforderung an den Endpunkt des Emulators senden.

docker-compose exec datastore bash ./import/run.sh

Referenz

Ich habe auf die folgende Seite verwiesen.

Recommended Posts

Starten Sie den Cloud Datastore Emulator mit Docker-Compose und arbeiten Sie mit der Python-App
Starten Sie einen Webserver mit Python und Flask
Python-Umgebung mit Docker-Compose
Einfache Verwendung der Nifty Cloud API mit Botocore und Python
Programmieren mit Python und Tkinter
Ver- und Entschlüsselung mit Python
Python und Hardware-Verwenden von RS232C mit Python-
Python mit Pyenv und Venv
Suchmaschinen arbeiten mit Python
Sammeln von Informationen von Twitter mit Python (Integration von MySQL und Python)
Funktioniert mit Python und R.
Erstellen Sie mit Python + Django + AWS eine Scraping-App und wechseln Sie Jobs
Kommunizieren Sie mit FX-5204PS mit Python und PyUSB
Leuchtendes Leben mit Python und OpenCV
[Paketwolke] Verwalten Sie Python-Pakete mit der Paketwolke
Roboter läuft mit Arduino und Python
Installieren Sie Python 2.7.9 und Python 3.4.x mit pip.
Neuronales Netzwerk mit OpenCV 3 und Python 3
AM-Modulation und Demodulation mit Python
Scraping mit Node, Ruby und Python
Scraping mit Python, Selen und Chromedriver
Kratzen mit Python und schöner Suppe
JSON-Codierung und -Decodierung mit Python
Führen Sie XGBoost mit Cloud Dataflow (Python) aus.
Hadoop-Einführung und MapReduce mit Python
[GUI in Python] PyQt5-Drag & Drop-
Lesen und Schreiben von NetCDF mit Python
Führe errBot ein und arbeite mit Slack
Ich habe mit PyQt5 und Python3 gespielt
Lesen und Schreiben von CSV mit Python
Mehrfachintegration mit Python und Sympy
Wenn matplotlib nicht mit python2.7 funktioniert
Koexistenz von Python2 und 3 mit CircleCI (1.0)
Sugoroku-Spiel und Zusatzspiel mit Python
FM-Modulation und Demodulation mit Python
Arbeiten Sie nicht mit Python mit OpenCV auf AMD Ryzen CPU unter WSL2 Ubuntu 18.04 und 20.04
Arbeitsnotiz zum Migrieren und Aktualisieren von Skripten der Python 2-Serie in der Cloud auf 3-Serien
Rabbit MQ Nachrichtenbenachrichtigungs-App mit Growl in Python ~ mit Raspeye und Julius ~
Automatisieren Sie Tastatur- und Mausoperationen mit Python, um die tägliche Arbeit zu optimieren [RPA]
Kommunizieren Sie mit gRPC zwischen Elixir und Python
Datenpipeline-Aufbau mit Python und Luigi
Berechnen Sie das Standardgewicht und zeigen Sie es mit Python an
Führen Sie Cloud Dataflow (Python) über AppEngine aus
Überwachen Sie Mojo-Ausfälle mit Python und Skype
[Automatisierung] Bearbeiten Sie Maus und Tastatur mit Python
Passwortlose Authentifizierung mit RDS und IAM (Python)
Python-Installation und Paketverwaltung mit pip
Onkel SES modernisiert die VBA-App mit Python
POST verschieden mit Python und empfange mit Flask
Bilder mit Pupil, Python und OpenCV aufnehmen
Fraktal zum Erstellen und Spielen mit Python
Ein Memo mit Python2.7 und Python3 in CentOS
Gemeinsamer Bildschirm mit Python Exe App
So arbeiten Sie mit BigQuery in Python
Versuchen Sie, Python mit Google Cloud-Funktionen zu verwenden
Verwenden Sie PIL oder Pillow mit Cygwin Python