Lancez l'émulateur Cloud Datastore avec docker-compose et travaillez avec l'application Python

Contexte

J'ai décidé d'utiliser le magasin de données pour le service, et j'ai essayé de faire des tests dans l'environnement de développement et CI. : en pensant: Puisqu'il y a moins d'informations par rapport à AWS, je les ai résumées. : souriant:

Le point

--Créez un conteneur pour l'application Flask et l'émulateur Cloud Datastore

Structure du répertoire

.
├── 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

Construction du conteneur de l'émulateur Cloud Datastore

datastore/Dockerfile

Création minimale à partir de l'image officielle du SDK. Accordez l'autorisation d'exécution au shell pour démarrer l'émulateur et au shell pour l'entrée de données.

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

Même lorsque docker-compose down est terminé, les données sont stockées dans le répertoire / datastore / .data / afin de conserver les données.

Si vous le démarrez sans options, vous ne pouvez y accéder qu'à l'intérieur du conteneur, alors démarrez-le en tant que --host-port = 0.0.0.0: 8081. À partir de la variable d'environnement, versez-la avec le nom du projet.

#!/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}

Data store / import / run.sh pour l'entrée de données

Après avoir démarré le serveur, vous pouvez importer les données en lançant le chemin de sauvegarde des données sauvegardées vers le point de terminaison suivant.

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"}'

banque de données / importation de métadonnées

Cette fois, depuis la console gcp, j'ai apporté tout le répertoire sauvegardé dans gcs sous datastore / import. Les données sdk peuvent être générées directement.

construction de conteneur d'application python

Créez une application fluide pour l'exemple.

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

Je pense que c'est un peu trop approprié, mais j'ai créé un point de terminaison qui enregistre et récupère simplement les données. : en pensant:

Les informations d'authentification mordent l'authentification factice.

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

Si vous ouvrez également le port de la banque de données côté hôte, vous pouvez le voir avec des outils d'interface graphique, ce qui est pratique.

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"

Commencez

docker-compose up 

Si vous accédez à http: // localhost: 5000 avec votre navigateur ou curl, vous devriez voir {"foo": "bar"}.

Journal

Vous pouvez voir que les données sont stockées ci-dessous

/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.

Entrée de données

Vous pouvez également importer des données de vidage en envoyant une demande au point de terminaison de l'émulateur.

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

référence

Je me suis référé au site suivant.

Recommended Posts

Lancez l'émulateur Cloud Datastore avec docker-compose et travaillez avec l'application Python
Lancer un serveur Web avec Python et Flask
environnement python avec docker-compose
API Nifty Cloud facile à utiliser avec botocore et python
Programmation avec Python et Tkinter
Chiffrement et déchiffrement avec Python
Python et matériel - Utilisation de RS232C avec Python -
python avec pyenv et venv
Les moteurs de recherche fonctionnent avec python
Collecte d'informations sur Twitter avec Python (intégration de MySQL et Python)
Fonctionne avec Python et R
Créez une application de scraping avec Python + Django + AWS et modifiez les tâches
Communiquez avec FX-5204PS avec Python et PyUSB
Briller la vie avec Python et OpenCV
[Package cloud] Gérez les packages python avec le package cloud
Robot fonctionnant avec Arduino et python
Installez Python 2.7.9 et Python 3.4.x avec pip.
Réseau neuronal avec OpenCV 3 et Python 3
Modulation et démodulation AM avec python
Scraping avec Node, Ruby et Python
Grattage avec Python, Selenium et Chromedriver
Grattage avec Python et belle soupe
Encodage et décodage JSON avec python
Exécutez XGBoost avec Cloud Dataflow (Python)
Introduction à Hadoop et MapReduce avec Python
[GUI en Python] PyQt5-Glisser-déposer-
Lire et écrire NetCDF avec Python
Introduisez errBot et travaillez avec Slack
J'ai joué avec PyQt5 et Python3
Lire et écrire du CSV avec Python
Intégration multiple avec Python et Sympy
Quand matplotlib ne fonctionne pas avec python2.7
Coexistence de Python2 et 3 avec CircleCI (1.0)
Jeu Sugoroku et jeu d'addition avec Python
Modulation et démodulation FM avec Python
Ne fonctionne pas Python avec OpenCV sur le processeur AMD Ryzen sur WSL2 Ubuntu 18.04 et 20.04
Note de travail pour migrer et mettre à jour les scripts de la série Python 2 sur le cloud vers la série 3
Application de notification de message Rabbit MQ avec Growl en Python ~ avec Raspeye et Julius ~
Automatisez les opérations du clavier et de la souris avec python pour rationaliser le travail quotidien [RPA]
Communiquez entre Elixir et Python avec gRPC
Construction de pipeline de données avec Python et Luigi
Calculer et afficher le poids standard avec python
Exécutez Cloud Dataflow (Python) depuis AppEngine
Surveiller les pannes de Mojo avec Python et Skype
[Automation] Manipulez la souris et le clavier avec Python
Authentification sans mot de passe avec RDS et IAM (Python)
Installation de Python et gestion des packages avec pip
Uncle SES modernise l'application VBA avec Python
POSTER diversement avec Python et recevoir avec Flask
Capturer des images avec Pupil, python et OpenCV
Fractal pour faire et jouer avec Python
Un mémo contenant Python2.7 et Python3 dans CentOS
Écran partagé avec l'application python exe
Comment utiliser BigQuery en Python
Essayez d'utiliser Python avec Google Cloud Functions
Utilisez PIL ou Pillow avec Cygwin Python