Lưu trữ an toàn các biến môi trường trong GAE với app.yaml


98

Tôi cần lưu trữ các khóa API và thông tin nhạy cảm khác app.yamldưới dạng các biến môi trường để triển khai trên GAE. Vấn đề với điều này là nếu tôi đẩy app.yamllên GitHub, thông tin này sẽ trở thành công khai (không tốt). Tôi không muốn lưu trữ thông tin trong kho dữ liệu vì nó không phù hợp với dự án. Thay vào đó, tôi muốn hoán đổi các giá trị từ một tệp được liệt kê trong .gitignoremỗi lần triển khai ứng dụng.

Đây là tệp app.yaml của tôi:

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}

Bất kỳ ý tưởng?


73
Tôi ước GAE sẽ thêm tùy chọn để đặt phiên bản env vars thông qua bảng điều khiển dành cho nhà phát triển (giống như mọi PaaS khác mà tôi quen thuộc).
Tàu Tây Ban Nha

4
Bạn có thể sử dụng kho dữ liệu. Vui lòng tham khảo câu trả lời này: stackoverflow.com/a/35254560/1027846
Mustafa İlhan

Mở rộng bình luận của mustilica ở trên về việc sử dụng kho dữ liệu. Xem câu trả lời của tôi bên dưới để biết mã tôi sử dụng trong các dự án của mình để thực hiện việc này: stackoverflow.com/a/35261091#35261091 . Trên thực tế, nó cho phép bạn chỉnh sửa các biến môi trường từ bảng điều khiển dành cho nhà phát triển và các giá trị trình giữ chỗ được tạo tự động.
Martin Omander

Cảm ơn mustilica và Martin. Chúng tôi thực sự đã sử dụng cách tiếp cận kho dữ liệu được một thời gian và tôi đồng ý rằng đó là giải pháp tốt nhất cho vấn đề này. Dễ dàng thực hiện với thiết lập CI / CD hơn so với cách tiếp cận tệp json, IMO.
Tàu Tây Ban Nha

1
2019 và GAE vẫn chưa khắc phục sự cố này: /
Josh Noe

Câu trả lời:


53

Nếu đó là dữ liệu nhạy cảm, bạn không nên lưu trữ nó trong mã nguồn vì nó sẽ được kiểm tra trong kiểm soát nguồn. Những người sai (bên trong hoặc bên ngoài tổ chức của bạn) có thể tìm thấy nó ở đó. Ngoài ra, môi trường phát triển của bạn có thể sử dụng các giá trị cấu hình khác với môi trường sản xuất của bạn. Nếu các giá trị này được lưu trữ trong mã, bạn sẽ phải chạy các mã khác nhau trong quá trình phát triển và sản xuất, điều này rất lộn xộn và không tốt.

Trong các dự án của mình, tôi đặt dữ liệu cấu hình vào kho dữ liệu bằng cách sử dụng lớp này:

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

Ứng dụng của bạn sẽ làm điều này để nhận được giá trị:

API_KEY = Settings.get('API_KEY')

Nếu có giá trị cho khóa đó trong kho dữ liệu, bạn sẽ nhận được nó. Nếu không có, một bản ghi giữ chỗ sẽ được tạo và một ngoại lệ sẽ được ném ra. Ngoại lệ sẽ nhắc bạn chuyển đến Bảng điều khiển dành cho nhà phát triển và cập nhật bản ghi giữ chỗ.

Tôi thấy điều này không cần phải phỏng đoán khi thiết lập các giá trị cấu hình. Nếu bạn không chắc chắn về những giá trị cấu hình nào cần đặt, chỉ cần chạy mã và nó sẽ cho bạn biết!

Đoạn mã trên sử dụng thư viện ndb sử dụng memcache và kho dữ liệu bên dưới, vì vậy nó rất nhanh.


Cập nhật:

jelder đã hỏi cách tìm các giá trị Kho dữ liệu trong bảng điều khiển App Engine và đặt chúng. Đây là cách:

  1. Tới https://console.cloud.google.com/datastore/

  2. Chọn dự án của bạn ở đầu trang nếu nó chưa được chọn.

  3. Trong hộp thả xuống Loại , chọn Cài đặt .

  4. Nếu bạn chạy mã trên, các khóa của bạn sẽ hiển thị. Tất cả chúng sẽ có giá trị KHÔNG ĐƯỢC ĐẶT . Nhấp vào từng cái và đặt giá trị của nó.

Hi vọng điêu nay co ich!

Cài đặt của bạn, được tạo bởi lớp Cài đặt

Bấm vào để chỉnh sửa

Nhập giá trị thực và lưu


2
Trong tất cả các câu trả lời được cung cấp, điều này có vẻ gần nhất với cách Heroku xử lý mọi thứ. Còn khá mới với GAE, tôi không hiểu rõ nơi trong Bảng điều khiển dành cho nhà phát triển để tìm bản ghi giữ chỗ. Bạn có thể giải thích, hoặc để có điểm thưởng, hãy đăng ảnh chụp màn hình?
jelder

2
dam ~… với tất cả sự liên quan đến gcloud, có vẻ khá tệ khi phải sử dụng một dịch vụ khác cho nhu cầu cụ thể này. Bên cạnh đó, google cung cấp phương pháp tiếp cận "100% -herokuish" cho env vars trong các hàm firebase, nhưng không cho các hàm gcloud (ít nhất là không có giấy tờ… nếu tôi không nhầm)
Ben

1
Dưới đây là một ý chính dựa trên cách tiếp cận của bạn có thêm tính độc đáo và biến môi trường dự phòng - gist.github.com/SpainTrain/6bf5896e6046a5d9e7e765d0defc8aa8
Tây Ban Nha Train

3
Các hàm @Ben Non-Firebase hỗ trợ env vars (ít nhất là bây giờ).
NReilingh

3
@obl - Ứng dụng App Engine được tự động xác thực vào kho dữ liệu của riêng nó, không cần chi tiết xác thực. Nó khá gọn gàng :-)
Martin Omander

49

Giải pháp này đơn giản nhưng có thể không phù hợp với tất cả các đội khác nhau.

Đầu tiên, đặt các biến môi trường trong env_variables.yaml , ví dụ:

env_variables:
  SECRET: 'my_secret'

Sau đó, bao gồm điều này env_variables.yamltrongapp.yaml

includes:
  - env_variables.yaml

Cuối cùng, thêm env_variables.yamlvào.gitignore các biến bí mật sẽ không tồn tại trong kho lưu trữ.

Trong trường hợp này, env_variables.yamlnhu cầu được chia sẻ giữa các nhà quản lý triển khai.


1
Chỉ cần thêm những gì có thể không được rõ ràng cho một số, các biến môi trường của bạn sau đó sẽ được tìm thấy trong process.env.MY_SECRET_KEYvà nếu bạn cần các biến môi trường trong môi trường dev địa phương của bạn, bạn có thể sử dụng nút dotenvgói
Dave Nụ hôn

2
Làm thế nào env_variables.yamlđể truy cập vào tất cả các trường hợp là một phần còn thiếu của câu đố.
Christopher Oezbek

1
Ngoài ra: Làm thế nào để sử dụng cục bộ này?
Christopher Oezbek

@ChristopherOezbek 1. Cách triển khai? Chỉ cần sử dụng gcloud app deploynhư bạn thường làm để triển khai lên Google Cloud. 2. Làm thế nào để thiết lập các biến môi trường bí mật cục bộ? Có rất nhiều cách. Bạn chỉ có thể sử dụng exporttrong dấu nhắc lệnh hoặc sử dụng bất kỳ công cụ nào như @DaveKiss được đề xuất.
Shih-Wen Su

Đây là giải pháp đơn giản nhất. Bí mật có thể được truy cập trong ứng dụng của bạn thông qua os.environ.get('SECRET').
Quinn Comendant, 13/07/19

19

Biện pháp của tôi là để lưu trữ bí mật của khách hàng chỉ trong ứng dụng App Engine riêng của mình. Các bí mật của máy khách không nằm trong kiểm soát nguồn cũng như trên bất kỳ máy tính cục bộ nào. Điều này có lợi ích mà bất kỳ cộng tác viên của App Engine nào cũng có thể triển khai các thay đổi mã mà không phải lo lắng về các bí mật của khách hàng.

Tôi lưu trữ bí mật của khách hàng trực tiếp trong Kho dữ liệu và sử dụng Memcache để cải thiện độ trễ khi truy cập bí mật. Các thực thể Kho dữ liệu chỉ cần được tạo một lần và sẽ tồn tại trong các lần triển khai sau này. tất nhiên bảng điều khiển App Engine có thể được sử dụng để cập nhật các thực thể này bất kỳ lúc nào.

Có hai tùy chọn để thực hiện tạo thực thể một lần:

  • Sử dụng trình bao tương tác API từ xa của App Engine để tạo các thực thể.
  • Tạo trình xử lý chỉ dành cho Quản trị viên sẽ khởi tạo các thực thể có giá trị giả. Gọi thủ công trình xử lý quản trị này, sau đó sử dụng bảng điều khiển App Engine để cập nhật các thực thể có bí mật của ứng dụng khách sản xuất.

7
Không phức tạp chút nào. Cảm ơn công cụ ứng dụng.
Courtimas

17

Điều này không tồn tại khi bạn đăng, nhưng đối với bất kỳ ai khác tình cờ vào đây, Google hiện cung cấp một dịch vụ có tên là Trình quản lý bí mật .

Đó là một dịch vụ REST đơn giản (tất nhiên với các SDK gói nó) để lưu trữ bí mật của bạn ở một vị trí an toàn trên nền tảng đám mây của google. Đây là một cách tiếp cận tốt hơn so với Data Store, yêu cầu các bước bổ sung để xem các bí mật được lưu trữ và có một mô hình cấp phép chi tiết hơn - bạn có thể bảo mật các bí mật riêng lẻ theo cách khác nhau cho các khía cạnh khác nhau của dự án, nếu bạn cần.

Nó cung cấp khả năng lập phiên bản, vì vậy bạn có thể xử lý các thay đổi mật khẩu tương đối dễ dàng, cũng như lớp quản lý và truy vấn mạnh mẽ cho phép bạn khám phá và tạo bí mật trong thời gian chạy, nếu cần.

SDK Python

Ví dụ sử dụng:

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

3
Đây phải là câu trả lời chính xác mới. Secret Manager vẫn đang trong giai đoạn Beta, nhưng đây là bước tiến khi làm việc với các biến môi trường.
King Leon

@KingLeon, sử dụng điều này có nghĩa là phải cấu trúc lại một loạt các os.getenv('ENV_VAR')s?
Alejandro

Tôi đặt mã tương tự như trên trong một hàm, sau đó tôi sử dụng một cái gì đó như SECRET_KEY = env('SECRET_KEY', default=access_secret_version(GOOGLE_CLOUD_PROJECT_ID, 'SECRET_KEY', 1)). Đặt mặc định để sử dụngaccess_secret_version
King Leon

Ngoài ra, tôi đang sử dụng django-environ. github.com/joke2k/django-environ
King Leon

16

Cách tốt nhất để làm điều đó, là lưu trữ các khóa trong tệp client_secrets.json và loại trừ khóa đó được tải lên git bằng cách liệt kê nó trong tệp .gitignore của bạn. Nếu bạn có các khóa khác nhau cho các môi trường khác nhau, bạn có thể sử dụng api app_identity để xác định id ứng dụng là gì và tải một cách thích hợp.

Có một ví dụ khá toàn diện ở đây -> https://developers.google.com/api-client-library/python/guide/aaa_client_secrets .

Đây là một số mã ví dụ:

# 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()

2
Chắc chắn là đúng hướng, nhưng điều này không giải quyết được vấn đề hoán đổi các giá trị app.yamlkhi triển khai ứng dụng. Bất kỳ ý tưởng ở đó?
Ben

1
Vì vậy, có một tệp client_secrets khác nhau cho mỗi môi trường. Ví dụ: client_secrets_live.json, client_secrets_dev.json, client_secrets_pilot.json, v.v., sau đó sử dụng python logic để xác định máy chủ bạn đang ở và tải lên tệp json thích hợp. Phương thức app_identity.get_application_id () có thể hữu ích để tự động phát hiện bạn đang sử dụng máy chủ nào. Đây có phải là loại điều bạn muốn nói?
Gwyn Howell

@BenGrunfeld xem câu trả lời của tôi. Giải pháp của tôi thực hiện chính xác điều này. Tôi không thấy câu trả lời này giải quyết câu hỏi như thế nào. Tôi giả sử mục tiêu là giữ cho cấu hình bí mật ngoài git và sử dụng git như một phần của quá trình triển khai. Ở đây, tệp này vẫn cần ở đâu đó và được đẩy vào quá trình triển khai. Đây có thể là điều bạn làm trong ứng dụng của mình, nhưng bạn sẽ chỉ sử dụng các kỹ thuật tôi đã đánh dấu, có thể lưu trữ trong một tệp khác nếu bạn muốn sử dụng ứng dụng này so với app.yaml. Nếu tôi hiểu câu hỏi, nó giống như việc vận chuyển một ứng dụng nguồn mở với bí mật hoặc sản phẩm khách hàng thực tế của nhà sản xuất thư viện. Chìa khóa.
therewillbesnacks

1
Tôi đã mất một lúc để tìm hiểu nó, nhưng tôi nghĩ đây là cách tiếp cận chính xác. Bạn không trộn cài đặt ứng dụng ( app.yaml) với khóa bí mật và thông tin bí mật, và điều tôi thực sự thích là bạn đang sử dụng quy trình làm việc của Google để hoàn thành nhiệm vụ. Cảm ơn @GwynHowell. =)
Ben

1
Cách tiếp cận tương tự sẽ là đặt tệp JSON đó ở một vị trí đã biết trong nhóm GCS mặc định của ứng dụng ( cloud.google.com/appengine/docs/standard/python/… ).
Tàu Tây Ban Nha

15

Giải pháp này dựa trên appcfg.py không được dùng nữa

Bạn có thể sử dụng tùy chọn dòng lệnh -E của appcfg.py để thiết lập các biến môi trường khi bạn triển khai ứng dụng của mình lên GAE (appcfg.py cập nhật)

$ 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).
...

Bạn có thể truy vấn các biến môi trường đó ở đâu đó sau khi triển khai không? (Tôi hy vọng là không.)
Ztyx

Có cách nào để chuyển các biến môi trường vào như thế này bằng cách sử dụng gcloudtiện ích không?
Trevor

6

Hầu hết các câu trả lời đã lỗi thời. Sử dụng kho dữ liệu đám mây của google thực sự có một chút khác biệt ngay bây giờ. https://cloud.google.com/python/getting-started/using-cloud-datastore

Đây là một ví dụ:

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')

Điều này giả sử tên thực thể là 'TWITTER_APP_KEY', loại là 'cài đặt' và 'giá trị' là thuộc tính của thực thể TWITTER_APP_KEY.


3

Có vẻ như bạn có thể thực hiện một số cách tiếp cận. Chúng tôi gặp sự cố tương tự và thực hiện như sau (điều chỉnh cho phù hợp với trường hợp sử dụng của bạn):

  • Tạo tệp lưu trữ bất kỳ giá trị app.yaml động nào và đặt nó trên máy chủ an toàn trong môi trường xây dựng của bạn. Nếu bạn thực sự hoang tưởng, bạn có thể mã hóa các giá trị một cách bất đối xứng. Bạn thậm chí có thể giữ nó trong một repo riêng tư nếu bạn cần kiểm soát phiên bản / kéo động hoặc chỉ cần sử dụng tập lệnh shell để sao chép / kéo nó từ nơi thích hợp.
  • Kéo từ git trong tập lệnh triển khai
  • Sau khi kéo git, hãy sửa đổi app.yaml bằng cách đọc và ghi nó bằng python thuần túy bằng thư viện yaml

Cách dễ nhất để làm điều này là sử dụng một máy chủ tích hợp liên tục như Hudson , Bamboo hoặc Jenkins . Chỉ cần thêm một số plugin, bước tập lệnh hoặc quy trình làm việc thực hiện tất cả các mục ở trên mà tôi đã đề cập. Ví dụ, bạn có thể chuyển các biến môi trường được cấu hình trong chính Bamboo.

Tóm lại, chỉ cần đẩy các giá trị trong quá trình xây dựng của bạn trong một môi trường mà bạn chỉ có quyền truy cập. Nếu bạn chưa tự động hóa các bản dựng của mình, bạn nên làm như vậy.

Một tùy chọn tùy chọn khác là những gì bạn đã nói, đưa nó vào cơ sở dữ liệu. Nếu lý do của bạn không làm điều đó là mọi thứ quá chậm, chỉ cần đẩy các giá trị vào memcache dưới dạng bộ nhớ cache lớp thứ 2 và ghim các giá trị vào các phiên bản dưới dạng bộ nhớ cache lớp thứ nhất. Nếu các giá trị có thể thay đổi và bạn cần cập nhật các phiên bản mà không cần khởi động lại chúng, chỉ cần giữ một hàm băm mà bạn có thể kiểm tra để biết khi nào chúng thay đổi hoặc kích hoạt nó bằng cách nào đó khi bạn làm thay đổi giá trị. Đó phải là nó.


1
FWIW, cách tiếp cận này tuân thủ chặt chẽ nhất yếu tố cấu hình trong nguyên tắc ứng dụng 12 Yếu tố ( 12factor.net )
Tây Ban Nha Train

3

Bạn nên mã hóa các biến bằng google kms và nhúng nó vào mã nguồn của bạn. ( 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

đặt giá trị xáo trộn (được mã hóa và mã hóa base64) vào biến môi trường của bạn (trong tệp yaml).

Một số mã pythonish để giúp bạn bắt đầu giải mã.

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

3

Câu trả lời của @Jason F dựa trên việc sử dụng Kho dữ liệu của Google là gần đúng, nhưng mã hơi lỗi thời dựa trên cách sử dụng mẫu trên tài liệu thư viện . Đây là đoạn mã phù hợp với tôi:

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'])

Một phần lấy cảm hứng từ bài đăng này trên Medium


2

Chỉ muốn lưu ý cách tôi đã giải quyết vấn đề này trong javascript / nodejs. Để phát triển cục bộ, tôi đã sử dụng gói npm 'dotenv' tải các biến môi trường từ tệp .env vào process.env. Khi tôi bắt đầu sử dụng GAE, tôi đã biết rằng các biến môi trường cần được đặt trong tệp 'app.yaml'. Chà, tôi không muốn sử dụng 'dotenv' để phát triển cục bộ và 'app.yaml' cho GAE (và sao chép các biến môi trường của tôi giữa hai tệp), vì vậy tôi đã viết một tập lệnh nhỏ tải các biến môi trường app.yaml vào quy trình .env, để phát triển địa phương. Hy vọng điều này sẽ giúp ai đó:

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]
        })
    }
})()

Bây giờ hãy bao gồm tệp này càng sớm càng tốt trong mã của bạn và bạn đã hoàn tất:

require('../yaml_env')

đây vẫn là trường hợp? Bởi vì tôi đang sử dụng một .envtệp có các biến bí mật. Tôi không sao chép chúng trong app.yamltệp của mình và mã đã triển khai của tôi vẫn hoạt động. Tuy nhiên, tôi lo lắng điều gì sẽ xảy ra với .envtệp trên đám mây. Nó có được mã hóa hay không? Làm cách nào để đảm bảo không có ai truy cập vào các .envbiến tệp gcloud khi nó được triển khai?
Gus

Điều này là không cần thiết vì GAE tự động thêm tất cả các biến được xác định trong tệp app.yaml vào môi trường nút. Về cơ bản, điều này giống như dotenv làm với các biến được xác định trong gói .env. Nhưng tôi đang tự hỏi làm thế nào bạn phải thiết lập CD như bạn không thể đẩy app.yaml với env VAR để một VCS hoặc một đường ống dẫn ...
Jornve

1

Mở rộng câu trả lời của Martin

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

1

Có một gói pypi được gọi là gae_env cho phép bạn lưu các biến môi trường appengine trong Cloud Datastore. Dưới mui xe, nó cũng sử dụng Memcache nên rất nhanh

Sử dụng:

import gae_env

API_KEY = gae_env.get('API_KEY')

Nếu có một giá trị cho khóa đó trong kho dữ liệu, nó sẽ được trả về. Nếu không có, một bản ghi giữ chỗ __NOT_SET__sẽ được tạo và một ValueNotSetErrorsẽ được ném. Ngoại lệ sẽ nhắc bạn chuyển đến Bảng điều khiển dành cho nhà phát triển và cập nhật bản ghi giữ chỗ.


Tương tự như câu trả lời của Martin, đây là cách cập nhật giá trị cho khóa trong Kho dữ liệu:

  1. Đi tới Phần kho dữ liệu trong bảng điều khiển dành cho nhà phát triển

  2. Chọn dự án của bạn ở đầu trang nếu nó chưa được chọn.

  3. Trong hộp thả xuống Loại , hãy chọn GaeEnvSettings.

  4. Các khóa mà ngoại lệ được nêu ra sẽ có giá trị __NOT_SET__.

Cài đặt của bạn, được tạo bởi lớp Cài đặt

Bấm vào để chỉnh sửa

Nhập giá trị thực và lưu


Tới trang GitHub của gói để biết thêm về cách sử dụng / cấu hình

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.