Sicheres Speichern von Umgebungsvariablen in GAE mit app.yaml

97

Ich muss API-Schlüssel und andere vertrauliche Informationen app.yamlals Umgebungsvariablen für die Bereitstellung auf GAE speichern . Das Problem dabei ist, dass app.yamldiese Informationen öffentlich werden (nicht gut) , wenn ich auf GitHub pushe. Ich möchte die Informationen nicht in einem Datenspeicher speichern, da sie nicht zum Projekt passen. Vielmehr möchte ich die Werte aus einer Datei austauschen, die in .gitignorejeder Bereitstellung der App aufgeführt ist.

Hier ist meine app.yaml Datei:

application: myapp
version: 3 
runtime: python27
api_version: 1
threadsafe: true

libraries:
- name: webapp2
  version: latest
- name: jinja2
  version: latest

handlers:
- url: /static
  static_dir: static

- url: /.*
  script: main.application  
  login: required
  secure: always
# auth_fail_action: unauthorized

env_variables:
  CLIENT_ID: ${CLIENT_ID}
  CLIENT_SECRET: ${CLIENT_SECRET}
  ORG: ${ORG}
  ACCESS_TOKEN: ${ACCESS_TOKEN}
  SESSION_SECRET: ${SESSION_SECRET}

Irgendwelche Ideen?

Ben
quelle
72
Ich wünschte, GAE würde die Option hinzufügen, Instanz-Umgebungsvariablen über die Entwicklerkonsole festzulegen (wie jedes andere PaaS, mit dem ich vertraut bin).
Spanien Zug
4
Sie können den Datenspeicher verwenden. Bitte beziehen Sie sich auf diese Antwort: stackoverflow.com/a/35254560/1027846
Mustafa İlhan
Erweitern Sie den obigen Kommentar von mustilica zur Verwendung des Datenspeichers. In meiner Antwort unten finden Sie Code, den ich in meinen Projekten dazu verwende: stackoverflow.com/a/35261091#35261091 . Tatsächlich können Sie Umgebungsvariablen über die Entwicklerkonsole bearbeiten, und Platzhalterwerte werden automatisch erstellt.
Martin Omander
Danke Mustilica und Martin. Wir verwenden den Datenspeicher-Ansatz bereits seit einiger Zeit und ich stimme zu, dass dies die beste Lösung für dieses Problem ist. Mit einem CI / CD-Setup einfacher zu tun als mit dem json-Dateiansatz IMO.
Spanien Zug
1
2019 und GAE haben dieses Problem immer noch nicht behoben: /
Josh Noe

Antworten:

53

Wenn es sich um vertrauliche Daten handelt, sollten Sie diese nicht im Quellcode speichern, da sie in die Quellcodeverwaltung eingecheckt werden. Die falschen Personen (innerhalb oder außerhalb Ihrer Organisation) können es dort finden. Außerdem verwendet Ihre Entwicklungsumgebung wahrscheinlich andere Konfigurationswerte als Ihre Produktionsumgebung. Wenn diese Werte im Code gespeichert sind, müssen Sie in Entwicklung und Produktion unterschiedlichen Code ausführen, was chaotisch und schlecht ist.

In meinen Projekten habe ich Konfigurationsdaten mit dieser Klasse in den Datenspeicher eingefügt:

from google.appengine.ext import ndb

class Settings(ndb.Model):
  name = ndb.StringProperty()
  value = ndb.StringProperty()

  @staticmethod
  def get(name):
    NOT_SET_VALUE = "NOT SET"
    retval = Settings.query(Settings.name == name).get()
    if not retval:
      retval = Settings()
      retval.name = name
      retval.value = NOT_SET_VALUE
      retval.put()
    if retval.value == NOT_SET_VALUE:
      raise Exception(('Setting %s not found in the database. A placeholder ' +
        'record has been created. Go to the Developers Console for your app ' +
        'in App Engine, look up the Settings record with name=%s and enter ' +
        'its value in that record\'s value field.') % (name, name))
    return retval.value

Ihre Anwendung würde dies tun, um einen Wert zu erhalten:

API_KEY = Settings.get('API_KEY')

Wenn der Datenspeicher einen Wert für diesen Schlüssel enthält, erhalten Sie ihn. Ist dies nicht der Fall, wird ein Platzhalterdatensatz erstellt und eine Ausnahme ausgelöst. Die Ausnahme erinnert Sie daran, zur Entwicklerkonsole zu wechseln und den Platzhalterdatensatz zu aktualisieren.

Ich finde, dies erleichtert das Erraten der Einstellung von Konfigurationswerten. Wenn Sie sich nicht sicher sind, welche Konfigurationswerte eingestellt werden sollen, führen Sie einfach den Code aus und er wird es Ihnen sagen!

Der obige Code verwendet die ndb-Bibliothek, die Memcache und den Datenspeicher unter der Haube verwendet, also ist es schnell.


Aktualisieren:

jelder fragte, wie die Datenspeicherwerte in der App Engine-Konsole gefunden und festgelegt werden könnten. Hier ist, wie:

  1. Gehen Sie zu https://console.cloud.google.com/datastore/

  2. Wählen Sie Ihr Projekt oben auf der Seite aus, falls es noch nicht ausgewählt ist.

  3. Wählen Sie im Dropdown-Feld Art die Option Einstellungen .

  4. Wenn Sie den obigen Code ausgeführt haben, werden Ihre Schlüssel angezeigt. Sie haben alle den Wert NOT SET . Klicken Sie auf jeden und legen Sie seinen Wert fest.

Hoffe das hilft!

Ihre Einstellungen, die von der Klasse "Einstellungen" erstellt wurden

Zum Bearbeiten anklicken

Geben Sie den tatsächlichen Wert ein und speichern Sie

Martin Omander
quelle
2
Von allen Antworten scheint dies der Art und Weise, wie Heroku mit Dingen umgeht, am nächsten zu kommen. Da ich für GAE ziemlich neu bin, verstehe ich nicht ganz, wo in der Entwicklerkonsole der Platzhalterdatensatz zu finden ist. Können Sie Screenshots erklären oder für Bonuspunkte posten?
Jelder
2
dam ~… bei allem Respekt vor gcloud sieht es ziemlich schlecht aus, einen anderen Dienst für diesen speziellen Bedarf nutzen zu müssen. Außerdem bietet Google einen "100% -herokuish" -Ansatz für env-Variablen innerhalb von Firebase-Funktionen, aber nicht für gcloud-Funktionen (zumindest ohne Papiere ... wenn ich mich nicht irre)
Ben
1
Hier ist ein Kern, der auf Ihrem Ansatz basiert und die Einzigartigkeit und den Fallback von Umgebungsvariablen hinzufügt - gist.github.com/SpainTrain/6bf5896e6046a5d9e7e765d0defc8aa8
Spain Train
3
@ Ben Non-Firebase-Funktionen unterstützen env-Variablen (zumindest jetzt).
NReilingh
3
@obl - Eine App Engine-App wird automatisch in ihrem eigenen Datenspeicher authentifiziert, ohne dass Authentifizierungsdetails erforderlich sind. Es ist ziemlich ordentlich :-)
Martin Omander
46

Diese Lösung ist einfach, eignet sich jedoch möglicherweise nicht für alle Teams.

Fügen Sie zunächst die Umgebungsvariablen in eine env_variables.yaml ein , z.

env_variables:
  SECRET: 'my_secret'

Fügen Sie dies dann env_variables.yamlin dieapp.yaml

includes:
  - env_variables.yaml

Fügen Sie abschließend das env_variables.yamlto hinzu .gitignore, damit die geheimen Variablen nicht im Repository vorhanden sind.

In diesem Fall env_variables.yamlmüssen die Bereitstellungsmanager gemeinsam genutzt werden.

Shih-Wen Su
quelle
1
Nur hinzufügen , was einige nicht offensichtlich sein kann, würde Ihre Umgebungsvariablen dann gefunden werden in , process.env.MY_SECRET_KEYund wenn Sie diese Umgebungsvariablen in Ihrem lokalen Entwickler - Umgebung benötigen , können Sie den Knoten verwenden dotenvPaket
Dave Kuss
2
Wie würde das env_variables.yamlErreichen aller Instanzen ein fehlendes Puzzleteil sein?
Christopher Oezbek
Außerdem: Wie wird dies lokal verwendet?
Christopher Oezbek
@ChristopherOezbek 1. Wie wird bereitgestellt? Verwenden gcloud app deploySie es einfach wie gewohnt, um es in Google Cloud bereitzustellen. 2. Wie werden geheime Umgebungsvariablen lokal festgelegt? Es gibt viele Wege. Sie können einfach exportdie Eingabeaufforderung verwenden oder Tools wie @DaveKiss vorschlagen.
Shih-Wen Su
Dies ist die einfachste Lösung. Auf Geheimnisse kann in Ihrer Anwendung über zugegriffen werden os.environ.get('SECRET').
Quinn Comendant
19

Mein Ansatz ist es, Kundengeheimnisse zu speichern nur in der App Engine-App selbst . Die Client-Geheimnisse befinden sich weder in der Quellcodeverwaltung noch auf lokalen Computern. Dies hat den Vorteil, dass jeder App Engine-Mitarbeiter Codeänderungen bereitstellen kann, ohne sich um die Client-Geheimnisse kümmern zu müssen.

Ich speichere Client-Geheimnisse direkt im Datenspeicher und verwende Memcache für eine verbesserte Latenz beim Zugriff auf die Geheimnisse. Die Datenspeicherentitäten müssen nur einmal erstellt werden und bleiben auch bei zukünftigen Bereitstellungen bestehen. Natürlich kann die App Engine-Konsole verwendet werden, um diese Entitäten jederzeit zu aktualisieren.

Es gibt zwei Möglichkeiten, um die einmalige Entitätserstellung durchzuführen:

  • Verwenden Sie die App Engine Remote API interaktive Shell , um die Entitäten zu erstellen.
  • Erstellen Sie einen Nur-Administrator-Handler, der die Entitäten mit Dummy-Werten initialisiert. Rufen Sie diesen Admin-Handler manuell auf und aktualisieren Sie die Entitäten mithilfe der App Engine-Konsole mit den Geheimnissen des Produktionsclients.
Bernd Verst
quelle
7
Gar nicht kompliziert. Danke App Engine.
Courtsimas
16

Der beste Weg, dies zu tun, besteht darin, die Schlüssel in einer client_secrets.json-Datei zu speichern und diese vom Hochladen auf git auszuschließen, indem Sie sie in Ihrer .gitignore-Datei auflisten. Wenn Sie unterschiedliche Schlüssel für unterschiedliche Umgebungen haben, können Sie mit der API app_identity die App-ID ermitteln und entsprechend laden.

Hier finden Sie ein ziemlich umfassendes Beispiel -> https://developers.google.com/api-client-library/python/guide/aaa_client_secrets .

Hier ist ein Beispielcode:

# declare your app ids as globals ...
APPID_LIVE = 'awesomeapp'
APPID_DEV = 'awesomeapp-dev'
APPID_PILOT = 'awesomeapp-pilot'

# create a dictionary mapping the app_ids to the filepaths ...
client_secrets_map = {APPID_LIVE:'client_secrets_live.json',
                      APPID_DEV:'client_secrets_dev.json',
                      APPID_PILOT:'client_secrets_pilot.json'}

# get the filename based on the current app_id ...
client_secrets_filename = client_secrets_map.get(
    app_identity.get_application_id(),
    APPID_DEV # fall back to dev
    )

# use the filename to construct the flow ...
flow = flow_from_clientsecrets(filename=client_secrets_filename,
                               scope=scope,
                               redirect_uri=redirect_uri)

# or, you could load up the json file manually if you need more control ...
f = open(client_secrets_filename, 'r')
client_secrets = json.loads(f.read())
f.close()
Gwyn Howell
quelle
2
Auf jeden Fall in die richtige Richtung, aber dies behebt nicht das Problem des Austauschs der Werte bei der app.yamlBereitstellung der App. Irgendwelche Ideen da?
Ben
1
Haben Sie also für jede Umgebung eine andere client_secrets-Datei. Beispiel: client_secrets_live.json, client_secrets_dev.json, client_secrets_pilot.json usw. Verwenden Sie dann die Python-Logik, um festzustellen, auf welchem ​​Server Sie sich befinden, und laden Sie die entsprechende JSON-Datei. Die Methode app_identity.get_application_id () kann hilfreich sein, um automatisch zu erkennen, auf welchem ​​Server Sie sich befinden. Ist das die Art von Dingen, die du meinst?
Gwyn Howell
@ BenGrunfeld siehe meine Antwort. Meine Lösung macht genau das. Ich sehe nicht, wie diese Antwort die Frage löst. Ich gehe davon aus, dass das Ziel darin besteht, die geheime Konfiguration von Git fernzuhalten und Git als Teil der Bereitstellung zu verwenden. Hier muss sich diese Datei noch irgendwo befinden und in den Bereitstellungsprozess verschoben werden. Dies kann etwas sein, das Sie in Ihrer App tun, aber Sie würden nur die Techniken verwenden, die ich hervorgehoben habe, und möglicherweise in einer anderen Datei speichern, wenn Sie diese vs. app.yaml verwenden möchten. Wenn ich die Frage verstehe, ähnelt dies dem Versand einer Open-Source-App mit dem tatsächlichen Kundengeheimnis oder Produkt des Bibliotheksherstellers. Schlüssel.
Therewillbesnacks
1
Ich habe eine Weile gebraucht, um mich darum zu kümmern, aber ich denke, das ist der richtige Ansatz. Sie mischen Anwendungseinstellungen ( app.yaml) nicht mit geheimen Schlüsseln und vertraulichen Informationen, und ich mag es wirklich, dass Sie den Google-Workflow verwenden, um die Aufgabe auszuführen. Danke @GwynHowell. =)
Ben
1
Ein ähnlicher Ansatz wäre, diese JSON-Datei an einem bekannten Speicherort im Standard-GCS-Bucket der App zu platzieren ( cloud.google.com/appengine/docs/standard/python/… ).
Spanien Zug
16

Dies gab es beim Posten noch nicht, aber für alle anderen, die hier stolpern, bietet Google jetzt einen Dienst namens Secret Manager an .

Es ist ein einfacher REST-Service (natürlich mit SDKs), um Ihre Geheimnisse an einem sicheren Ort auf der Google Cloud-Plattform zu speichern. Dies ist ein besserer Ansatz als der Datenspeicher, da zusätzliche Schritte erforderlich sind, um die gespeicherten Geheimnisse anzuzeigen, und über ein detaillierteres Berechtigungsmodell verfügen. Sie können einzelne Geheimnisse für verschiedene Aspekte Ihres Projekts bei Bedarf unterschiedlich sichern.

Es bietet eine Versionierung, sodass Sie Kennwortänderungen relativ einfach verarbeiten können, sowie eine robuste Abfrage- und Verwaltungsebene, mit der Sie bei Bedarf zur Laufzeit Geheimnisse entdecken und erstellen können.

Python SDK

Anwendungsbeispiel:

from google.cloud import secretmanager_v1beta1 as secretmanager

secret_id = 'my_secret_key'
project_id = 'my_project'
version = 1    # use the management tools to determine version at runtime

client = secretmanager.SecretManagerServiceClient()

secret_path = client.secret_verion_path(project_id, secret_id, version)
response = client.access_secret_version(secret_path)
password_string = response.payload.data.decode('UTF-8')

# use password_string -- set up database connection, call third party service, whatever
Randolpho
quelle
3
Dies sollte die neue richtige Antwort sein. Secret Manager befindet sich noch in der Beta-Phase, dies ist jedoch der richtige Weg, wenn Sie mit Umgebungsvariablen arbeiten.
König Leon
@KingLeon, würde dies bedeuten, ein paar os.getenv('ENV_VAR')s umgestalten zu müssen ?
Alejandro
Ich füge Code ähnlich wie oben in eine Funktion ein und verwende dann so etwas wie SECRET_KEY = env('SECRET_KEY', default=access_secret_version(GOOGLE_CLOUD_PROJECT_ID, 'SECRET_KEY', 1)). Festlegen der Standardeinstellung für die Verwendung vonaccess_secret_version
King Leon
Außerdem benutze ich Django-Environ. github.com/joke2k/django-environ
König Leon
15

Diese Lösung basiert auf der veralteten appcfg.py

Sie können die Befehlszeilenoption -E von appcfg.py verwenden, um die Umgebungsvariablen einzurichten, wenn Sie Ihre App für GAE bereitstellen (appcfg.py-Update).

$ appcfg.py
...
-E NAME:VALUE, --env_variable=NAME:VALUE
                    Set an environment variable, potentially overriding an
                    env_variable value from app.yaml file (flag may be
                    repeated to set multiple variables).
...
jla
quelle
Können Sie diese Umgebungsvariablen irgendwo nach der Bereitstellung abfragen? (Ich hoffe nicht.)
Ztyx
Gibt es eine Möglichkeit, Umgebungsvariablen mit dem gcloudDienstprogramm wie folgt zu übergeben?
Trevor
6

Die meisten Antworten sind veraltet. Die Verwendung des Google Cloud-Datenspeichers ist derzeit etwas anders. https://cloud.google.com/python/getting-started/using-cloud-datastore

Hier ist ein Beispiel:

from google.cloud import datastore
client = datastore.Client()
datastore_entity = client.get(client.key('settings', 'TWITTER_APP_KEY'))
connection_string_prod = datastore_entity.get('value')

Dies setzt voraus, dass der Entitätsname 'TWITTER_APP_KEY' ist, die Art 'settings' ist und 'value' eine Eigenschaft der Entität TWITTER_APP_KEY ist.

Jason F.
quelle
3

Es hört sich so an, als könnten Sie ein paar Ansätze machen. Wir haben ein ähnliches Problem und gehen wie folgt vor (angepasst an Ihren Anwendungsfall):

  • Erstellen Sie eine Datei, in der alle dynamischen app.yaml-Werte gespeichert sind, und platzieren Sie sie auf einem sicheren Server in Ihrer Build-Umgebung. Wenn Sie wirklich paranoid sind, können Sie die Werte asymmetrisch verschlüsseln. Sie können dies sogar in einem privaten Repo aufbewahren, wenn Sie Versionskontrolle / dynamisches Ziehen benötigen, oder einfach ein Shells-Skript verwenden, um es zu kopieren / von der entsprechenden Stelle zu ziehen.
  • Ziehen Sie während des Bereitstellungsskripts aus git
  • Ändern Sie nach dem Git-Pull die Datei app.yaml, indem Sie sie mit einer yaml-Bibliothek in reinem Python lesen und schreiben

Der einfachste Weg, dies zu tun, ist die Verwendung eines kontinuierlichen Integrationsservers wie Hudson , Bamboo oder Jenkins . Fügen Sie einfach ein Plug-In, einen Skriptschritt oder einen Workflow hinzu, der alle oben genannten Elemente ausführt. Sie können Umgebungsvariablen übergeben, die beispielsweise in Bamboo selbst konfiguriert sind.

Zusammenfassend lässt sich sagen, dass Sie die Werte während des Erstellungsprozesses in einer Umgebung eingeben, auf die Sie nur Zugriff haben. Wenn Sie Ihre Builds noch nicht automatisieren, sollten Sie dies tun.

Eine andere Option Option ist, was Sie gesagt haben, setzen Sie es in die Datenbank. Wenn Sie dies nicht tun, weil die Dinge zu langsam sind, verschieben Sie die Werte einfach als Cache der zweiten Ebene in den Memcache und heften Sie die Werte als Cache der ersten Ebene an die Instanzen an. Wenn sich die Werte ändern können und Sie die Instanzen aktualisieren müssen, ohne sie neu zu starten, behalten Sie einfach einen Hash bei, den Sie überprüfen können, um zu wissen, wann sie sich ändern, oder lösen Sie ihn irgendwie aus, wenn Sie die Werte ändern. Das sollte es sein.

therewillbesnacks
quelle
1
FWIW, dieser Ansatz folgt am ehesten dem Konfigurationsfaktor in den 12-Faktor-App-Richtlinien ( 12factor.net )
Spanien Zug
3

Sie sollten die Variablen mit Google KMS verschlüsseln und in Ihren Quellcode einbetten. ( https://cloud.google.com/kms/ )

echo -n the-twitter-app-key | gcloud kms encrypt \
> --project my-project \
> --location us-central1 \
> --keyring THEKEYRING \
> --key THECRYPTOKEY \
> --plaintext-file - \
> --ciphertext-file - \
> | base64

Fügen Sie den verschlüsselten (verschlüsselten und base64-codierten) Wert in Ihre Umgebungsvariable (in der Yaml-Datei) ein.

Einige Python-Codes, mit denen Sie mit dem Entschlüsseln beginnen können.

kms_client = kms_v1.KeyManagementServiceClient()
name = kms_client.crypto_key_path_path("project", "global", "THEKEYRING", "THECRYPTOKEY")

twitter_app_key = kms_client.decrypt(name, base64.b64decode(os.environ.get("TWITTER_APP_KEY"))).plaintext
Anders Elton
quelle
3

Die Antwort von @Jason F, die auf der Verwendung von Google Datastore basiert, ist knapp, aber der Code ist aufgrund der Beispielverwendung in den Bibliotheksdokumenten etwas veraltet . Hier ist der Ausschnitt, der für mich funktioniert hat:

from google.cloud import datastore

client = datastore.Client('<your project id>')
key = client.key('<kind e.g settings>', '<entity name>') # note: entity name not property
# get by key for this entity
result = client.get(key)
print(result) # prints all the properties ( a dict). index a specific value like result['MY_SECRET_KEY'])

Teilweise inspiriert von diesem Medium-Beitrag

kip2
quelle
2

Ich wollte nur wissen, wie ich dieses Problem in Javascript / NodeJS gelöst habe. Für die lokale Entwicklung habe ich das Paket 'dotenv' npm verwendet, das Umgebungsvariablen aus einer .env-Datei in process.env lädt. Als ich anfing, GAE zu verwenden, habe ich gelernt, dass Umgebungsvariablen in einer 'app.yaml'-Datei festgelegt werden müssen. Nun, ich wollte nicht 'dotenv' für die lokale Entwicklung und 'app.yaml' für GAE verwenden (und meine Umgebungsvariablen zwischen den beiden Dateien duplizieren), also habe ich ein kleines Skript geschrieben, das die Umgebungsvariablen app.yaml in den Prozess lädt .env, für die lokale Entwicklung. Hoffe das hilft jemandem:

yaml_env.js:

(function () {
    const yaml = require('js-yaml');
    const fs = require('fs');
    const isObject = require('lodash.isobject')

    var doc = yaml.safeLoad(
        fs.readFileSync('app.yaml', 'utf8'), 
        { json: true }
    );

    // The .env file will take precedence over the settings the app.yaml file
    // which allows me to override stuff in app.yaml (the database connection string (DATABASE_URL), for example)
    // This is optional of course. If you don't use dotenv then remove this line:
    require('dotenv/config');

    if(isObject(doc) && isObject(doc.env_variables)) {
        Object.keys(doc.env_variables).forEach(function (key) {
            // Dont set environment with the yaml file value if it's already set
            process.env[key] = process.env[key] || doc.env_variables[key]
        })
    }
})()

Fügen Sie diese Datei nun so früh wie möglich in Ihren Code ein, und Sie sind fertig:

require('../yaml_env')
gbruins
quelle
Ist das noch der Fall? Weil ich eine .envDatei mit den geheimen Variablen verwende. Ich dupliziere sie nicht in meiner app.yamlDatei und mein bereitgestellter Code funktioniert immer noch. Ich mache mir allerdings Sorgen, was mit der .envDatei in der Cloud passiert . Wird es verschlüsselt oder so? Wie kann ich sicherstellen, dass nach der Bereitstellung niemand auf die .envVariablen der gcloud- Datei zugreift ?
Gus
Dies ist überhaupt nicht erforderlich, da GAE automatisch alle in der Datei app.yaml definierten Variablen zur Knotenumgebung hinzufügt. Grundsätzlich ist dies dasselbe wie bei dotenv mit Variablen, die im .env-Paket definiert sind. Aber ich frage mich, wie Sie eine CD einrichten müssen, da Sie app.yaml mit env vars nicht auf ein VCS oder eine Pipeline übertragen können ...
Jornve
1

Martins Antwort erweitern

from google.appengine.ext import ndb

class Settings(ndb.Model):
    """
    Get sensitive data setting from DataStore.

    key:String -> value:String
    key:String -> Exception

    Thanks to: Martin Omander @ Stackoverflow
    https://stackoverflow.com/a/35261091/1463812
    """
    name = ndb.StringProperty()
    value = ndb.StringProperty()

    @staticmethod
    def get(name):
        retval = Settings.query(Settings.name == name).get()
        if not retval:
            raise Exception(('Setting %s not found in the database. A placeholder ' +
                             'record has been created. Go to the Developers Console for your app ' +
                             'in App Engine, look up the Settings record with name=%s and enter ' +
                             'its value in that record\'s value field.') % (name, name))
        return retval.value

    @staticmethod
    def set(name, value):
        exists = Settings.query(Settings.name == name).get()
        if not exists:
            s = Settings(name=name, value=value)
            s.put()
        else:
            exists.value = value
            exists.put()

        return True
JSBach
quelle
1

Es gibt ein Pypi-Paket namens gae_env , mit dem Sie Appengine-Umgebungsvariablen im Cloud-Datenspeicher speichern können. Unter der Haube verwendet es auch Memcache, so dass es schnell ist

Verwendung:

import gae_env

API_KEY = gae_env.get('API_KEY')

Wenn der Datenspeicher einen Wert für diesen Schlüssel enthält, wird dieser zurückgegeben. Ist dies nicht der __NOT_SET__Fall , wird ein Platzhalterdatensatz erstellt und ein ValueNotSetErrorgeworfen. Die Ausnahme erinnert Sie daran, zur Entwicklerkonsole zu wechseln und den Platzhalterdatensatz zu aktualisieren.


Ähnlich wie bei Martins Antwort können Sie den Wert für den Schlüssel im Datenspeicher wie folgt aktualisieren:

  1. Wechseln Sie in der Entwicklerkonsole zum Abschnitt Datenspeicher

  2. Wählen Sie Ihr Projekt oben auf der Seite aus, falls es noch nicht ausgewählt ist.

  3. Wählen Sie im Dropdown-Feld Art die Option aus GaeEnvSettings.

  4. Schlüssel, für die eine Ausnahme ausgelöst wurde, haben Wert __NOT_SET__.

Ihre Einstellungen, die von der Klasse "Einstellungen" erstellt wurden

Zum Bearbeiten anklicken

Geben Sie den tatsächlichen Wert ein und speichern Sie


Weitere Informationen zur Verwendung / Konfiguration finden Sie auf der GitHub-Seite des Pakets

Prinz Odame
quelle